一般来说,使用条件运算符时,语法如下:
int x = 6;
int y = x == 6 ? 5 : 9;
没什么花哨的,非常简单。
现在,让我们尝试在将 Lambda 分配给 Func 类型时使用它。 让我解释一下:
Func<Order, bool> predicate = id == null
? p => p.EmployeeID == null
: p => p.EmployeeID == id;
这是相同的语法,应该可以工作吗? 正确的? 由于某种原因,事实并非如此。 编译器给出了这个很好的神秘消息:
错误1无法确定条件表达式的类型,因为“lambda表达式”和“lambda表达式”之间没有隐式转换
然后我继续更改语法,这样它就起作用了:
Func<Order, bool> predicate = id == null
? predicate = p => p.EmployeeID == null
: predicate = p => p.EmployeeID == id;
我只是好奇为什么第一种方式不起作用?
(旁注:我最终不需要这段代码,因为我发现在将 int 值与 null 进行比较时,您只需使用 object.Equals)
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)
发布评论
评论(4)
您可以将 lambda 表达式转换为特定的目标委托类型,但为了确定条件表达式的类型,编译器需要知道第二个和第三个操作数中每个操作数的类型。 虽然它们都只是“lambda 表达式”,但没有从一个到另一个的转换,因此编译器无法执行任何有用的操作。
不过,我不建议使用赋值 - 强制转换更为明显:
请注意,您只需为一个操作数提供它,这样编译器就可以执行来自其他 lambda 表达式的转换。
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:
Note that you only need to provide it for one operand, so the compiler can perform the conversion from the other lambda expression.
C# 编译器无法推断所创建的 lambda 表达式的类型,因为它首先处理三元,然后处理赋值。 你也可以这样做:
但这很糟糕,
你也可以尝试
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:
but that just sucks,
you could also try
让我有自己的例子,因为我也遇到了同样的问题(希望该示例对其他人有帮助):
我的
Find
方法是获取Expression>
作为谓词,并给出List
作为输出。我想查找国家/地区,但如果语言列表为空,我需要所有国家/地区;如果语言列表已填满,我需要过滤列表。
首先,我使用了如下代码:
但我确实得到了错误:
lambda 表达式和 lambda 表达式之间没有隐式转换。
问题是,我们这里只有两个 lambda 表达式,没有其他任何东西,例如,什么是
country => 完全正确? 我们必须确定至少一个 lambda 表达式的类型。 如果仅确定其中一个表达式,则将忽略错误。 但为了使代码更具可读性,我提取了两个 lambda 表达式,并使用变量代替,如下所示:
我强调,如果我只确定其中一种表达式的类型,则错误将被修复。
Let me have my own example since I had the same problem, too (with the hope that the example be helpful for others):
My
Find
method is generic method that getsExpression<Func<T, bool>>
as predicate and givesList<T>
as output.I wanted to find countries, but I need all of them if language list was empty, and filtered list, if language list was filled.
First I used the Code as below:
But exactly I get the error :
there is no implicit conversion between lambda expression and lambda expression.
The problem was that, we have just two lambda expressions here, and nothing else, for example, what is
country => true
exactly?? We have to determine the type of at least one of lambda expressions. If just of one of the expressions be determined, then the error will be omitted. But for make the code more readable, I extracted both lambda expressions, and used the variable instead, as below:I emphasize that, if I just determined one of the expression's type, the error will be fixed.
只是更新 - 在 C# 10 中,编译器现在可以推断 lambda 的“自然类型”,前提是提供了输入类型,例如
这也意味着 0 输入可以推断出功能和动作:
但是,这行不通:
因此,现在可以做OP最初想做的事情,前提是至少提供了输入类型,例如,
但是,这仍然不是'允许:
Just an update - in C# 10, it IS now possible for the compiler to infer the 'natural type' of a lambda, provided that the input type(s) are provided, e.g.
This also means that 0 input Funcs and Actions can be inferred:
However, this won't work:
As a result, it is now possible to do what the OP originally wanted to do, provided that at least the input types are provided, e.g.
However, this still isn't permitted: