Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I assign a Func<> conditionally between lambdas using the conditional ternary operator?

Generally, when using the conditional operator, here's the syntax:

int x = 6; int y = x == 6 ? 5 : 9; 

Nothing fancy, pretty straight forward.

Now, let's try to use this when assigning a Lambda to a Func type. Let me explain:

Func<Order, bool> predicate = id == null     ? p => p.EmployeeID == null     : p => p.EmployeeID == id; 

That's the same syntax, and should work? Right? For some reason that doesn't. The compiler gives this nice cryptic message:

Error 1 Type of conditional expression cannot be determined because there is no implicit conversion between 'lambda expression' and 'lambda expression'

I then went ahead and changed the syntax and this way it did work:

Func<Order, bool> predicate = id == null     ? predicate = p => p.EmployeeID == null     : predicate = p => p.EmployeeID == id; 

I'm just curious as to why it doesn't work the first way?

(Side note: I ended up not needing this code, as I found out that when comparing an int value against null, you just use object.Equals)

like image 629
BFree Avatar asked Nov 04 '08 19:11

BFree


People also ask

How do you write a conditional statement using the ternary operator?

The conditional (ternary) operator is the only JavaScript operator that takes three operands: a condition followed by a question mark ( ? ), then an expression to execute if the condition is truthy followed by a colon ( : ), and finally the expression to execute if the condition is falsy.

Can we use ternary operator in lambda expression?

The conditional operator is used to make conditional expressions in Java. It is also called a Ternary operator because it has three operands such as boolean condition, first expression, and second expression. We can also write a conditional expression in lambda expression in the below program.

Can ternary operator have two conditions?

In the above syntax, we have tested 2 conditions in a single statement using the ternary operator. In the syntax, if condition1 is incorrect then Expression3 will be executed else if condition1 is correct then the output depends on the condition2. If condition2 is correct, then the output is Expression1.

Can you use functions in ternary operator?

Nope, you can only assign values when doing ternary operations, not execute functions.


2 Answers

You can convert a lambda expression to a particular target delegate type, but in order to determine the type of the conditional expression, the compiler needs to know the type of each of the second and third operands. While they're both just "lambda expression" there's no conversion from one to the other, so the compiler can't do anything useful.

I wouldn't suggest using an assignment, however - a cast is more obvious:

Func<Order, bool> predicate = id == null      ? (Func<Order, bool>) (p => p.EmployeeID == null)     : p => p.EmployeeID == id; 

Note that you only need to provide it for one operand, so the compiler can perform the conversion from the other lambda expression.

like image 105
Jon Skeet Avatar answered Sep 28 '22 09:09

Jon Skeet


The C# compiler cannot infer the type of the created lambda expression because it processes the ternary first and then the assignment. you could also do:

Func<Order, bool> predicate =      id == null ?          new Func<Order,bool>(p => p.EmployeeID == null) :         new Func<Order,bool>(p => p.EmployeeID == id); 

but that just sucks, you could also try

Func<Order, bool> predicate =      id == null ?          (Order p) => p.EmployeeID == null :         (Order p) => p.EmployeeID == id; 
like image 25
Jake Avatar answered Sep 28 '22 09:09

Jake