Conditional operator cannot cast implicitly?
我有点被这个小怪癖难住了:
给定变量:
1 2 | Boolean aBoolValue; Byte aByteValue; |
以下汇编:
1 2 3 4 | if (aBoolValue) aByteValue = 1; else aByteValue = 0; |
但这不会:
1 | aByteValue = aBoolValue ? 1 : 0; |
错误说明:"无法将类型"int"隐式转换为"byte"。
当然,这个怪物会编译:
1 | aByteValue = aBoolValue ? (byte)1 : (byte)0; |
这是怎么回事?
编辑:
使用VS2008,c 3.5
这是一个相当常见的问题。
在C中,我们几乎总是从内到外推理。当你看到
1 | x = y; |
我们计算出x的类型,y的类型,以及y的类型是否与x兼容,但是我们不使用这样一个事实:当我们计算出y的类型时,我们知道x的类型是什么。
这是因为可能有多个X:
1 2 3 4 | 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)。因为它不是常量,所以不能将其赋给byte;当结果不是常量时,编译器只根据类型而不是值进行推理。
所有这些规则的例外是lambda表达式,其中类型信息确实从上下文流入lambda。要把逻辑搞好是非常困难的。
我使用的是VS2005,因为我可以为布尔型(bool&boolean)复制,但不是真的。
1 2 3 4 5 | bool abool = true; Boolean aboolean = true; Byte by1 = (abool ? 1 : 2); //Cannot implicitly convert type 'int' to 'byte' Byte by2 = (aboolean ? 1 : 2); //Cannot implicitly convert type 'int' to 'byte' Byte by3 = (true ? 1 : 2); //Warning: unreachable code ;) |
最简单的解决方法似乎是
1 | Byte by1 = (Byte)(aboolean ? 1 : 2); |
因此,是的,三元运算符似乎导致常量"固定"它们的类型为int,并禁用隐式类型转换,否则您将从适合较小类型的常量中获得这种转换。
我对你的回答也许不是很好,但如果你在许多地方这样做,你可以声明:
1 2 | private static readonly Byte valueZero = (byte)0; private static readonly Byte valueOne = (byte)1; |
只有这些变量。如果
编辑:使用