这个C#怪癖让我有些困惑:
给定变量:
Boolean aBoolValue; Byte aByteValue;
编译如下:
if (aBoolValue) aByteValue = 1; else aByteValue = 0;
但这不会:
aByteValue = aBoolValue ? 1 : 0;
错误消息:“无法将类型’int’隐式转换为’byte’。”
当然,这种怪兽会编译为:
aByteValue = aBoolValue ? (byte)1 : (byte)0;
这里发生了什么?
编辑:
使用VS2008,C#3.5
这是一个相当常见的问题。
在C#中,我们几乎总是从内到外进行推理。当你看到
x = y;
我们计算出x的类型是什么,y的类型是什么,以及y的类型是否与x兼容。但是,当我们计算y的类型时,我们不会使用知道x的类型的事实。
那是因为可能有多个x:
void M(int x) { } void M(string x) { } ... M(y); // y is assigned to either int x or string x depending on the type of y
我们 需要 能够计算出表达式的类型, 而无需 知道将其分配给什么。型信息流 出来 的表达,而不是 成 的表达式。
为了计算条件表达式的类型,我们计算结果的类型和替代表达式,从两种类型中选择更通用的类型,这便成为条件表达式的类型。因此,在您的示例中,条件表达式的类型为“ int”,并且它不是常量(除非条件表达式为true或false常量)。由于它不是一个常量,因此无法将其分配给字节。当结果不是常量时,编译器将仅根据类型而不是根据值进行解释。
所有这些规则的例外是lambda表达式,其中类型信息 确实 从上下文流入lambda。正确地处理逻辑非常困难。