简体   繁体   English

C#函数和条件运算符

[英]C# Func and Conditional Operator

Duplicate 重复

I can do this: 我可以做这个:

Func<CategorySummary, decimal> orderByFunc;
if (orderBy == OrderProductsByProperty.Speed)
     orderByFunc = x => x.Speed;
else
    orderByFunc = x => x.Price;

Why can't I do this: 我为什么不能这样做:

Func<CategorySummary, decimal> orderByFunc = (orderBy == OrderProductsByProperty.Speed) ? x => x.Speed : x => x.Price;

The 'type inference' on the conditional operator is not quite good enough, I get a message like 条件运算符上的“类型推断”还不够好,我收到一条类似

Type of conditional expression cannot be determined because there is no implicit conversion between 'lambda expression' and 'lambda expression' 无法确定条件表达式的类型,因为“ lambda表达式”和“ lambda表达式”之间没有隐式转换

you can always just be explicit on the right-hand-side, a la 您总是可以在右侧保持明确

var o = true ? new Func<int,int>(x => 0) : new Func<int,int>(x => 1);

In any case it's just a minor annoyance regarding how the types of lambdas, type inference, and the conditional operator interact. 无论如何,这只是关于lambda类型,类型推断和条件运算符如何交互的一个小麻烦。

只需将lambda转换为Func<CategorySummary, decimal> ,它将起作用

An alternative to the suggestions so far - move the conditional inside the lambda expression: 到目前为止建议的替代方法-在lambda表达式内移动条件:

Func<CategorySummary, decimal> orderByFunc = 
    x => (orderBy == OrderProductsByProperty.Speed) ? x.Speed : x.Price;

It may not be suitable in all situations (and it does mean that the check is performed on every invocation) but sometimes it could be useful. 它可能并不适用于所有情况(它确实意味着检查是在每次调用时执行的),但有时它可能会有用。

EDIT: As Eric points out, the two are not equivalent. 编辑:正如埃里克(Eric)指出的那样,两者并不等效。 Here's a quick example of how they differ (using explicit casting to get the conditional to work where the operands are lambdas): 这是一个简单的示例,说明它们之间的区别(使用显式强制转换以使条件在操作数为lambda的情况下起作用):

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();
    }
}

Results: 结果:

Before change...
Outer: I hate cheese
Inner: I hate cheese
After change...
Outer: I hate cheese
Inner: I like cheese

As you can see, the change to the value of likesCheese only affects the version which has the conditional operator inside the lambda expression. 如您所见,对likesCheese值的likesCheese仅影响在lambda表达式具有条件运算符的版本。 Sometimes this is desirable, sometimes not... but you definitely need to be aware of it. 有时这是理想的,有时不是……但是您绝对需要意识到这一点。

It's enough to cast only one resulting operand to a target type: 仅将一个结果操作数转换为目标类型就足够了:

Action showResult = true 
    ? (Action)(() => Console.Write("Hello!"))
    : () => Console.Write("");

It was a little unexpected, but this is how compiler works. 有点意外,但这就是编译器的工作方式。 And when I think about it, it makes sense now. 当我考虑到这一点时,它就有意义了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM