我可以这样做:
Func<CategorySummary, decimal> orderByFunc;
if (orderBy == OrderProductsByProperty.Speed)
orderByFunc = x => x.Speed;
else
orderByFunc = x => x.Price;
为什么我不能这样做:
Func<CategorySummary, decimal> orderByFunc = (orderBy == OrderProductsByProperty.Speed) ? x => x.Speed : x => x.Price;
答案 0 :(得分:6)
条件运算符上的'类型推断'不够好,我收到了像
这样的消息条件表达式的类型不能 确定是因为没有 'lambda之间的隐式转换 表达'和'lambda表达'
你总是可以在右手边明确表达,而
var o = true ? new Func<int,int>(x => 0) : new Func<int,int>(x => 1);
在任何情况下,对于lambdas类型,类型推断和条件运算符的交互方式,这只是一个小麻烦。
答案 1 :(得分:3)
将lambda's转换为Func<CategorySummary, decimal>
,它将起作用
答案 2 :(得分:1)
目前为止建议的替代方法 - 在lambda表达式中移动条件:
Func<CategorySummary, decimal> orderByFunc =
x => (orderBy == OrderProductsByProperty.Speed) ? x.Speed : x.Price;
它可能不适用于所有情况(并且它确实意味着在每次调用时都执行检查)但有时它可能有用。
编辑:埃里克指出,这两者并不相同。下面是一个快速示例,说明它们的区别(使用显式转换使条件在操作数为lambdas的地方工作):using System;
class Test
{
static void Main()
{
bool likesCheese = false;
Action outerConditional = likesCheese
? (Action) (() => Console.WriteLine("Outer: I like cheese"))
: (Action) (() => Console.WriteLine("Outer: I hate cheese"));
Action innerConditional = () =>
Console.WriteLine (likesCheese ? "Inner: I like cheese"
: "Inner: I hate cheese");
Console.WriteLine("Before change...");
outerConditional();
innerConditional();
likesCheese = true;
Console.WriteLine("After change...");
outerConditional();
innerConditional();
}
}
结果:
Before change...
Outer: I hate cheese
Inner: I hate cheese
After change...
Outer: I hate cheese
Inner: I like cheese
正如您所看到的,对likesCheese
值的更改仅影响具有条件运算符 in lambda表达式的版本。有时这是可取的,有时候不是......但你肯定需要注意它。
答案 3 :(得分:0)
只能将一个结果操作数转换为目标类型:
Action showResult = true
? (Action)(() => Console.Write("Hello!"))
: () => Console.Write("");
这有点出乎意料,但这就是编译器的工作原理。当我想到它时,现在就有意义了。