In c# can I do something like this in a shorthand?
bool validName = true;
if (validName)
{
name = "Daniel";
surname = "Smith";
}
else
{
MessageBox.Show("Invalid name");
}
I was just wondering if something similar to this would work, but in this exact scenario, I know you can assign values if I did name = validName ? "Daniel" : "Not valid", but I was just wondering if i can do the below?
validName ?
{
name = "Daniel";
surname = "Smith";
}
:
{
MessageBox.Show("Invalid name");
}
Abusing lambda syntax and type inference:
(validName
? (Action)
(() =>
{
name = "Daniel";
surname = "Smith";
})
: () =>
{
MessageBox.Show("Invalid name");
})();
I know, not really an answer. If statement is way better: obviously this syntax is less readable and more importantly it has different runtime behaviour and could lead to unintended side effects because of potential closures created by the lambda expressions.
Syntax is a bit cryptic too. It first creates two Action objects then ?: operator chooses between them and at last the chosen result is executed:
var a1 = new Action(() => { /* if code block */ });
var a2 = new Action(() => { /* else code block */ });
Action resultingAction = test_variable ? a1 : a2;
resultingAction();
I put it together in one statement by executing the resulting action in place. To make it even briefer I cast the first lambda expression into an Action (instead of creating a new Action() explicitly) and taking advantage of type inference I left out the second cast.
No.
The ternary operator (?:) must be, as a whole, an expression -- that is, something that can be assigned to something.
Let's say you could do that. Why?
What is the motivation?
Fewer lines? not enough to make a difference.
Performance? None, the compiler will handle things for you.
Clarity? If/else is clearer and more easily understood by the majority of developers.
I am sure, if you worked hard enough, you could find a way to handle this (most likely a kludge), but I still cannot determine the why.
The conditional operator requires its second and third operands to be expressions that return a value (in addition to meeting some type restrictions) and not statements that do not resolve to a value. You have no value that you wish to return from either operation you are currently performing.
You could return some nonsensical value just for the sake of making the code compile, but at that point you're adding a ton more work than just using an if which is the correct semantic operator for your requirements, so while it is technically possible, it is not a good idea.
fullName = validName == true ? returnName(firstName)+" "+returnName(lastName) : validName == false ? invalidName("Invalid Name") : null
public string returnName(string name)
{
return name;
}
public string invalidName(string invalid)
{
MessageBox.Show(invalid);
return null;
}
As everyone else has probably said it's something you likely won't really want to do, but, it is possible :P
Related
I'm trying to understand writing anonymous Methods in C#.
But having trouble to achieve a success.
Please have a look at my example.
I'm trying to fill a property named Value by given conditions.
When I would write a private helper method which takes an inputparam int lockCardStatus and returns a string that would be a solution but my intention is to try this with a "quickshot" like so:
MailMessageTextPlaceholders = new List<MailMessageTextPlaceholder>
{
new MailMessageTextPlaceholder
{
PlaceholderName = "status",
Value = y =>
{
switch (_lockCard.Status)
{
case (int)LockCard.LockCardStatus.Done :
return "Is Done";
case (int)LockCard.LockCardStatus.Pending :
return "Is in Pending status";
case (int)LockCard.LockCardStatus.Open :
return "Has been created";
default:
return "No status yet!";
}
}
}
}
Unfortunately the compiler says:
Lambda Expression cannot be converted to type string because it is not a delgate.
The error arises because the compiler interprets this line:
Value = y => {...}
as an assignment. It thinks you want to assign the lambda expression to Value. But the types don't match! Value is a string and not a delegate of any kind. For detailed information see Compiler Error CS1660
What you actually want is to execute this lambda and assign the resulting value. To accomplish that you can define the delegate and the return value at creation of the lambda using Func<string>. and execute it on the spot by using the ( ) parentheses like in a normal method call:
MailMessageTextPlaceholder hodler = new MailMessageTextPlaceholder()
{
Value = new Func<string>(() =>
{
switch (_lockCard.Status)
{
case (int)LockCard.LockCardStatus.Done:
return "Is Done";
case (int)LockCard.LockCardStatus.Pending:
return "Is in Pending status";
case (int)LockCard.LockCardStatus.Open:
return "Has been created";
default:
return "No status yet!";
}
})() // <- this executes the method!
};
And suddenly this stuff becomes compileable.
EDIT:
Apparently the compiler is not able to infer the return type and thus specify the delegate type on its own. This can be illustrated by this example:
var asd = () => { return "XXX"; };
This line results in the error:
CS0815 Cannot assign lambda expression to an implicitly-typed variable
But excplicit specification of the delegate type resolves this error:
var asd = new Func<string>(() => { return "XXX";});
This indicates that the explicit specification of the delegate type is necessary and essential.
What you are trying to do is not available (yet) in C# since switch statements cannot be evaluated unambiguously to one return value. A reason for this is that switch cases may contain any arbitrary code and not just one expression.
There will be a new way of writing switch statements in C# 8 that makes your code possible.
You may solve your problem by creating a helper method:
MailMessageTextPlaceholders = new List<MailMessageTextPlaceholder>
{
new MailMessageTextPlaceholder
{
PlaceholderName = "status",
Value = GetStatusDescription(_lockCard.Status)
}
}
string GetStatusDescription(LockCard.LockCardStatus status)
{
switch (status)
{
case (int)LockCard.LockCardStatus.Done :
return "Is Done";
case (int)LockCard.LockCardStatus.Pending :
return "Is in Pending status";
case (int)LockCard.LockCardStatus.Open :
return "Has been created";
default:
return "No status yet!";
}
}
and the helper method may be a local function
If you still really, really wish to inline your string mapping you may nest ternary operator statements.
MailMessageTextPlaceholders = new List<MailMessageTextPlaceholder>
{
new MailMessageTextPlaceholder
{
PlaceholderName = "status",
Value =
status == LockCard.LockCardStatus.Done
? "Is Done";
: status == LockCard.LockCardStatus.Pending
? "Is in Pending status"
: status == LockCard.LockCardStatus.Open
? "Has been created"
: "No status yet!";
}
}
When you are using ternary operators, C# will be able to unambiguously evaluate the result, which makes the compiler happy.
You may also solve your problem by adding description attributes to your enum
a ?? b
If a is not null => returns a.
Else (a is null) => returns b.
I want to simulate something like its inverse (AFAIK there is no operator to do this):
If a is null => return a.
Else (a is not null) => returns b.
The idea is that b would be the result of a function that receives a and needs to avoid null parameters. Like this: a XX fn(a) where XX would be the operator (if it exists).
My only two variants are:
a == null ? a : fn(a)
a == null ? null : fn(a)
Is there any way to simplify this code?
Not sure exactly what you're trying to accomplish? Something like this?
TResult NullFn<TParam, TResult>(TParam a, Func<TParam, TResult> method)
{
if(a == null) return null;
return method(a);
}
...
var result = NullFn(a, a => fn(a))
But the best solution IMHO would be to just have fn return null if it is passed a null value.
EDIT:
The method at the top is only an example. You might want to use something like this in a situation where you've got a LOT of the same operation over and over again in a specific area and you can't change fn because it would make is easier to focus on the rest of the code and there's a chance you might want to alter the null-handling behavior for all your operations at once in the future. (I'm assuming that is the case because you're asking in the first place.) But I wouldn't use this across an entire application because it isn't clear what's happening if you don't have the NullFn function right in front of you.
Whats wrong with simple condition?
if (a != null) b = fn(a);
Another option - add a condition to your method:
public B fn(A a)
{
if (a == null)
return null;
return new B();
}
Personally I would prefer
(a != null) ? fn(a) : null
because I think it makes the intention more obvious, but I can not think of a way to simplify that much. You could use an extension method if you like.
a.CallIfNotNull(fn)
with the following extension method
internal static T CallIfNotNull<T>(this T value, Func<T, T> function)
where T : class
{
return (value != null) ? function(value) : null;
}
Not really better but probably less error prone and easier to type given IntelliSense.
(Is assumed the function returns a value of the same type as the argument as the question suggests.)
If you have T a; and T fn(T a); using the same user-defined type T, then you can write a && fn(a) and it will expand to T.False(a) ? a : T.&(a, fn(a)).
You've answered your own question with the ?: implementations at the bottom.
The only improvement i would suggest is to wrap the functionality in a method that makes it cleaner and less error prone to do.
object SafeB(object a)
{
return a==null ? a : b(a);
}
The compiler will probably inline this so you won't lose performance.
You may even be able to implement it as an extension method of the class that provides b so that it becomes an even more integrated solution.
Before you start criticizing and pointing me §8.7.2 of C# specification, read carefully :)
We all know how switch looks like in C#. Ok so consider the class MainWindow with "nasty" Bar method
static int barCounter = 0;
public static int Bar()
{
return ++barCounter;
}
Somewhere in this class we have code like this
Action switchCode = () =>
{
switch (Bar())
{
case 1:
Console.WriteLine("First");
break;
case 2:
Console.WriteLine("Second");
break;
}
};
switchCode();
switchCode();
In the console window we will see
First
Second
Using Expressions in C# we could do the same – writing much same code
var switchValue = Expression.Call(typeof(MainWindow).GetMethod("Bar"));
var WriteLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) });
var #switch = Expression.Switch(switchValue,
Expression.SwitchCase(
Expression.Call(WriteLine, Expression.Constant("First")),
Expression.Constant(1)
),
Expression.SwitchCase(
Expression.Call(WriteLine, Expression.Constant("Second")),
Expression.Constant(2)
)
);
Action switchCode = Expression.Lambda<Action>(#switch).Compile();
switchCode();
switchCode();
In DebugView we could see "code behind" this expression
.Switch (.Call WpfApplication1.MainWindow.Bar()) {
.Case (1):
.Call System.Console.WriteLine("First")
.Case (2):
.Call System.Console.WriteLine("Second")
}
Ehmm, what if we use Expression.Call instead Expression.Constant?
public static bool foo1() { return false; }
public static bool foo2() { return true; }
// .....
var foo1 = Ex.Call(typeof(MainWindow).GetMethod("foo1"));
var foo2 = Ex.Call(typeof(MainWindow).GetMethod("foo2"));
var switchValue = Ex.Call(typeof(MainWindow).GetMethod("Bar"));
var WriteLine = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) });
var #switch = Ex.Switch(Ex.Constant(true),
Ex.SwitchCase(
Ex.Call(WriteLine, Ex.Constant("First")),
foo1
),
Ex.SwitchCase(
Ex.Call(WriteLine, Ex.Constant("OK!")),
Ex.Equal(switchValue, Ex.Constant(2))
),
Ex.SwitchCase(
Ex.Call(WriteLine, Ex.Constant("Second")),
foo2
)
);
Action switchCode = Ex.Lambda<Action>(#switch).Compile();
switchCode();
switchCode();
Console window shows, as we expected
Second
OK!
And DebugView
.Switch (True) {
.Case (.Call WpfApplication1.MainWindow.foo1()):
.Call System.Console.WriteLine("First")
.Case (.Call WpfApplication1.MainWindow.Bar() == 2):
.Call System.Console.WriteLine("OK!")
.Case (.Call WpfApplication1.MainWindow.foo2()):
.Call System.Console.WriteLine("Second")
}
So it is possible to use non-constant expression in case-statement :)
Ok, I known this is little ‘messy’ code. But here comes my question (finally :P):
Is there any way to extends functionality of IDE/VisualStudio/compiler to do this, but with more elegant code?
Something like this
switch (true)
{
case foo1():
Console.WriteLine("First");
break;
case Bar() == 2:
Console.WriteLine("OK!");
break;
case foo2():
Console.WriteLine("Second");
break;
}
I know this will be some extension and code will be not the same (not the same performance). But I wonder if this is even possible to "change" code on-the-fly – like anonymous function or yield return is transform to nested class.
I hope someone goes through the above text and leave some clue.
In general, there are no extension points in the Microsoft C# compiler as far as I know (and even Roslyn isn't planning to change that). But nothing is stopping you from writing your own C# compiler, or, more realistically, modifying the open source Mono C# compiler.
In any case, I think it's much more trouble than what it's worth.
But maybe you can do what you want using something that's already in the language, namely, lambdas and method calls, to form a “fluent switch”:
Switch.Value(true)
.Case(() => Foo(), () => Console.WriteLine("foo"))
.Case(() => Bar() == 2, () => Console.WriteLine("bar == 2"));
If you don't mind that all the condition values will be evaluated every time, you simplify that a bit:
Switch.Value(true)
.Case(Foo(), () => Console.WriteLine("foo"))
.Case(Bar() == 2, () => Console.WriteLine("bar == 2"));
No, it's not possible, nor that I'm aware of. It's already kind of miracle that you can use a string inside switch statement (reference type with immutable behavior). For these kind of cases just use if, if/else, if/elseif combinations.
There aren't currently extensions that do that sort of thing. Although it's worth pointing out that MS SQL allows for exactly what you are looking for
SELECT
Column1, Column2,
CASE
WHEN SomeCondition THEN Column3
WHEN SomeOtherCondition THEN Column4
END AS CustomColumn
FROM ...
The problem with this becomes understanding precedence; what happens when both conditions are true? In SQL the case statement returns the value from the first statement that is true, and ignores other cases, but that behavior might not be what you wanted.
The strength of C# is that it's impossible to code switches in such a way that both case 1 and case 2 can be true at the same time, so you are guaranteed only one correct answer.
As we all know "Switches" exposes a similar functionality to an if. Most of us (myself include) see it as a syntax sugar -- it's easier to read a bunch of cases on a certain switch then read through a number of if/else if/.../else. But the fact is that switch is no syntax sugar.
What you must realize is that the code generated for switch (be it IL or machine code) is not the same as the code generated for sequential ifs. Switch has a nice optimization which, as #Ed S. already pointed out, enables it to run in a constant time.
(for LISP hackers in short: I'm looking for the LISP-quote equivalent in C#)
I'm trying to write a meaningful ToString-method for a class which has a Func as member. Experiened API-users can set this member via setter-method like
myClassObject.SetFunction( (x) => x*x );
Now, when I use the ToString-method on the member it only returns
System.Func<double,double>
which is not very helpful. What would be helpful is
"(x) => x*X"
Is there any (preferable easy) way to do that?
Thanks for any help or comments.
Edit: corrected some typos
Expression<Func<double,double>> expr = x => x * x;
string s = expr.ToString(); // "x => (x * x)"
If you're willing to store your delegate as an expression, you can achieve what you want. The code would look something like this:
private Expression<Func<double, double>> myFunc;
private Func<double, double> cachedDelegate;
public void SetFunc(Expression<Func<double,double>> newFunc)
{
this.myFunc = newFunc;
this.cachedDelegate = null;
}
public double ExecFunc(double x)
{
if (this.myFunc != null)
{
if (this.cachedDelegate != null)
{
return this.cachedDelegate(x);
}
else
{
this.cachedDelegate = this.myFunc.Compile();
return this.cachedDelegate(x);
}
}
return 0.0;
}
public string GetFuncText()
{
if (this.myFunc != null)
{
return this.myFunc.ToString();
}
return "";
}
In order to actually use the lambda expression, you have to compile it first. Storing it in a delegate means you only take that hit once.
Also, this approach means that users have to use a lambda, since method groups aren't convertible to Expression<Func<>>. That's not a huge concern, though, since instead of passing MyMethod, a user could pass x => MyMethod(x).
The calling code would look something like this:
myObject.SetFunc(x => 2*x);
Console.WriteLine(myObject.GetFuncText());
One final note is that the above sample is not thread-safe, so if you expect to have the methods called from multiple threads, some sort of synchronization would be appropriate.
None that I know of since that string has never entered the system, only IL was somehow generated and stored with a reference... you would need to "decompile" the IL to some meaningful string...
With CodeExpression there is possibility to call GenerateCodeFromExpression via an instance of CodeDomProvider which has built-in implementations for C# / VB / JScript... but I would be surprised if that met your needs...
Another option: With Expression you could use ToString() - this works with LambdaExpression too since that is just a descendant.
So I'm working on a project where I need to parse an expression tree. I got most of the things working, but I've run into a bit of a problem.
I've been looking at the other questions on StackOverflow on Expression Trees, but can't seem to find an answer to my question, so here goes.
My problem is the difference (or lack of) between constants and variables. Let me start off with an example:
user => user.Email == email
This is clearly not a constant but a variable, but this ends up being a ConstantExpression somewhere in the expression tree. If you take a look at the expression itself, it looks a bit odd:
Expression = {value(stORM.Web.Security.User+<>c__DisplayClassa)}
If we take another example:
task => task.Status != TaskStatus.Done && t.Status != TaskStatus.Failed
Here I'm using an ENUM (TaskStatus).
So my problem is that in the tree parsing I seem to end up with a ConstantExpression in both cases, and I really need to be able to tell them apart. These are just examples, so what I'm asking is a generic way of telling these two types of expression from each other, so I can handle then in 2 different ways in my parsing.
EDIT: okay, my examples might not be clear, so I'll try again. First example:
User user = db.Search < User > (u => u.Email == email);
I'm trying to find a user with the given e-mail address. I'm parsing this into a stored procedure, but that's besides the point I guess.
Second example:
IList < Task > tasks = db.Search(t => t.Status != TaskStatus.Done && t.Status != TaskStatus.Failed);
And here I'm trying to locate all tasks with a status different from Done and Failed.
Again this is being parsing into a stored procedure. In the first example my code needs to determine that the stored procedure needs a input parameter, the value of the email variable. In the second example I don't need any input parameters, I just need to create the SQL for selecting task with a status different from Done and Failed.
Thanks again
So from the point of view of expression the value is a constant. It can not be changed by the expression.
What you have is a potentially open closure - i.e. the value can change between executions of the expression, but not during it. So it is a "constant". This is a paradigm difference between the world of functional programming and un-functional :) programming.
Consider
int a =2;
Expression<Func<int, int>> h = x=> x+ a;
Expression<Func<int, int>> j = x => x +2;
a = 1;
the term a is a member access into an anonymous class that wraps up and access the a variable on the stack. The first node is a MemberAccess node then underneath that - the expression is a constant.
For the code above:
((SimpleBinaryExpression)(h.Body)).Right
{value(WindowsFormsApplication6.Form1+<>c__DisplayClass0).a}
CanReduce: false
DebugView: ".Constant<WindowsFormsApplication6.Form1+<>c__DisplayClass0>(WindowsFormsApplication6.Form1+<>c__DisplayClass0).a"
Expression: {value(WindowsFormsApplication6.Form1+<>c__DisplayClass0)}
Member: {Int32 a}
NodeType: MemberAccess
Type: {Name = "Int32" FullName = "System.Int32"}
And the constant underneath that:
((MemberExpression)((SimpleBinaryExpression)(h.Body)).Right).Expression
{value(WindowsFormsApplication6.Form1+<>c__DisplayClass0)}
CanReduce: false
DebugView: ".Constant<WindowsFormsApplication6.Form1+<>c__DisplayClass0>(WindowsFormsApplication6.Form1+<>c__DisplayClass0)"
NodeType: Constant
Type: {Name = "<>c__DisplayClass0" FullName = "WindowsFormsApplication6.Form1+<>c__DisplayClass0"}
Value: {WindowsFormsApplication6.Form1.}
}
}
The plain old 2 comes out to a:
((SimpleBinaryExpression)(j.Body)).Right
{2}
CanReduce: false
DebugView: "2"
NodeType: Constant
Type: {Name = "Int32" FullName = "System.Int32"}
Value: 2
So I don't know if that helps you or not. You can kind of tell by looking at the parent node - or the type of object being accessed by the parent node.
Adding as a result of your clarification -
so when you say
user => user.Email == email
You mean look for all users with an email equal to a passed in parameter - however that link expression means something quite different.
what you want to say is
Expression<Func<User, string, bool>> (user, email) => user.Email == email
This way the email will now be a parameter. If you don't like that there is one other thing you can do.
The second example will work just fine - no extra params are needed consts will be consts.
t => t.Status != TaskStatus.Done && t.Status != TaskStatus.Failed
Edit: adding another way:
So one of the things that you had to do to get your code working was declare a string email outside the lambda - that is kind of clunky.
You could better identify parameters by conventionally putting them in a specific place - like a static class. Then when going through the Lambda you don't have to look at some horrible cloture object - but a nice static class of your making.
public static class Parameter
{
public static T Input<T>(string name)
{
return default(T);
}
}
Then your code looks like this:
Expression<Func<User, bool>> exp = x => x.Email == Parameter.Input<String>("email");
You can then traverse the tree - when you come to a call to to the Parameter static class you can look at the type and the name (in the arguments collection) and off you go....
The name is a bit unfortunate, it is not actually a constant.
It simply refers to a value outside the Expression.
A captured variable (the first case with email) is typically a ConstantExpression representing the capture class instance, with a MemberExpression to a FieldInfo for the "variable" - as if you had:
private class CaptureClass {
public string email;
}
...
var obj = new CaptureClass();
obj.email = "foo#bar.com";
Here, obj is the constant inside the expression.
So: if you see a MemberExpression (of a field) to a ConstantExpression, it is probably a captured variable. You could also check for CompilerGeneratedAttribute on the capture-class...
A literal constant will typically just be a ConstantExpression; in fact, it would be hard to think of a scenario where you use a constant's member, unless you could something like:
() => "abc".Length
but here .Length is a property (not a field), and the string probably doesn't have [CompilerGenerated].
Just check the Type of the ConstantExpression. Any 'constant' ConstantExpression has a primitive type.