三元(条件)运算符和if语句返回Action之间的区别

时间:2013-12-02 20:25:31

标签: c# if-statement ternary-operator

考虑以下不编译的代码:

class WhyNot
{
    private Action _doSomething;
    public bool ThisOrThat;

    public WhyNot()
    {
        _doSomething = ThisOrThat ?  DoThis : DoThat;   
    }
    private void DoThis()
    {}
    private void DoThat()
    {}
}

我知道这不起作用,因为methods dont intrisically have a type,而代表则这样做,所以explicit cast must be made

_doSomething = ThisOrThat ? (Action)DoThis : (Action)DoThat;    

我不遵循的原因是为什么标准if语句成功地在三元运算符失败的情况下进行转换?

if (ThisOrThat)
    _doSomething = DoThis;
else
    _doSomething = DoThat;

为什么运营商之间存在差异?

3 个答案:

答案 0 :(得分:5)

  

为什么在条件运算符

中需要显式强制转换
_doSomething = ThisOrThat ?  DoThis : DoThat; 

来自Jon Skeet的this answer

  

作为表达。那是什么类型的?委托类型应该是什么   方法组转换为? 编译器没办法   知道即可。如果您转换其中一个操作数,编译器可以检查   另一个可以转换

对于你的问题:

  

为什么if声明

允许这样做

您正在做一个简单的任务,左侧是Action,右侧是方法组。存在隐式转化

请参阅Assignment Operator(=) C#

  

赋值运算符(=)存储其右侧操作数的值   在左侧表示的存储位置,属性或索引器中   操作数并返回值作为结果。操作数必须是   相同的类型(或右侧操作数必须是隐式的   可转换为左手操作数的类型

答案 1 :(得分:2)

三元运算符根据真假条件的类型推断结果的类型。在推断类型时,编译器不会在三元运算符之前考虑赋值运算符。

当您尝试编译三元语句时,它会推断出三元运算符的结果类型是一个方法组,由于方法没有类型,因此无法将其指定为变量。这与您的三元运算符之前的简单赋值无关:失败严格地在三元语句中导致两个方法组与两个委托。

if语句中,您使用的是简单的等于运算符=。因此,编译器会将隐式转换的方法组类型推断为您的委托,因此它基本上成为Action = (Action)method成功。

最终,这是关于三元运算符的行为,并且无法确定两个方法组的类型。他们是代表吗?如果是这样,哪位代表?它无法知道,因此你必须告诉它通过显式转换使用什么委托。

相关的C#语言规范条目:

7.12 Conditional Operator

7.13.1 Simple Assignment

6.1.4 Implicit Reference Conversions

答案 2 :(得分:1)

这与if语句或赋值运算符无关。问题完全在于三元条件。来自文档:

?:运算符的第二个和第三个操作数控制条件表达式的类型。设X和Y是第二个和第三个操作数的类型。然后,

如果X和Y是相同的类型,那么这是条件表达式的类型。 否则,如果从X到Y存在隐式转换(第6.1节),但不存在
从Y到X,则Y是条件的类型 表达。
否则,如果从Y到X存在隐式转换(第6.1节),但不存在
从X到Y,则X是条件的类型 表达。
否则,无法确定表达式类型,并发生编译时错误。

当您尝试直接分配方法时,可以隐式转换它。