考虑以下不编译的代码:
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;
为什么运营商之间存在差异?
答案 0 :(得分:5)
为什么在条件运算符
中需要显式强制转换
_doSomething = ThisOrThat ? DoThis : DoThat;
来自Jon Skeet的this answer:
作为表达。那是什么类型的?委托类型应该是什么 方法组转换为? 编译器没办法 知道即可。如果您转换其中一个操作数,编译器可以检查 另一个可以转换
对于你的问题:
为什么
允许这样做if
声明
您正在做一个简单的任务,左侧是Action
,右侧是方法组。存在隐式转化
赋值运算符(=)存储其右侧操作数的值 在左侧表示的存储位置,属性或索引器中 操作数并返回值作为结果。操作数必须是 相同的类型(或右侧操作数必须是隐式的 可转换为左手操作数的类型)
答案 1 :(得分:2)
三元运算符根据真假条件的类型推断结果的类型。在推断类型时,编译器不会在三元运算符之前考虑赋值运算符。
当您尝试编译三元语句时,它会推断出三元运算符的结果类型是一个方法组,由于方法没有类型,因此无法将其指定为变量。这与您的三元运算符之前的简单赋值无关:失败严格地在三元语句中导致两个方法组与两个委托。
在if
语句中,您使用的是简单的等于运算符=
。因此,编译器会将隐式转换的方法组类型推断为您的委托,因此它基本上成为Action = (Action)method
成功。
最终,这是关于三元运算符的行为,并且无法确定两个方法组的类型。他们是代表吗?如果是这样,哪位代表?它无法知道,因此你必须告诉它通过显式转换使用什么委托。
相关的C#语言规范条目:
答案 2 :(得分:1)
这与if
语句或赋值运算符无关。问题完全在于三元条件。来自文档:
?:运算符的第二个和第三个操作数控制条件表达式的类型。设X和Y是第二个和第三个操作数的类型。然后,
如果X和Y是相同的类型,那么这是条件表达式的类型。
否则,如果从X到Y存在隐式转换(第6.1节),但不存在
从Y到X,则Y是条件的类型
表达。
否则,如果从Y到X存在隐式转换(第6.1节),但不存在
从X到Y,则X是条件的类型
表达。
否则,无法确定表达式类型,并发生编译时错误。
当您尝试直接分配方法时,可以隐式转换它。