C#Func和条件运算符

时间:2009-05-17 03:49:25

标签: c#

Duplicate

我可以这样做:

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;

4 个答案:

答案 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("");

这有点出乎意料,但这就是编译器的工作原理。当我想到它时,现在就有意义了。