条件运算符不能隐式转换?
我对 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
I'm a little stumped by this little C# quirk:
Given variables:
Boolean aBoolValue;
Byte aByteValue;
The following compiles:
if (aBoolValue)
aByteValue = 1;
else
aByteValue = 0;
But this will not:
aByteValue = aBoolValue ? 1 : 0;
Error says: "Cannot implicitly convert type 'int' to 'byte'."
And of course, this monstrosity will compile:
aByteValue = aBoolValue ? (byte)1 : (byte)0;
What's going on here?
EDIT:
Using VS2008, C# 3.5
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
这是一个相当常见的问题。
在 C# 中,我们几乎总是从内到外进行推理。当你看到
我们计算出x的类型是什么,y的类型是什么,以及y的类型是否与x的赋值兼容。但是当我们计算 y 的类型时,我们并没有使用我们知道 x 的类型这一事实。
这是因为可能有多个 x:
我们需要能够在不知道表达式被分配给什么的情况下计算出它的类型。类型信息从表达式流出,而不是流入表达式。
为了计算出条件表达式的类型,我们计算出结果和替代表达式的类型,选择两种类型中更通用的一个,这将成为条件表达式的类型。因此,在您的示例中,条件表达式的类型是“int”,并且它不是常量(除非条件表达式为常量 true 或常量 false)。由于它不是常量,因此不能将其分配给 byte;当结果不是常量时,编译器仅根据类型而不是值进行推理。
所有这些规则的例外是 lambda 表达式,其中类型信息确实从上下文流入 lambda。获得正确的逻辑非常困难。
This is a fairly frequently asked question.
In C#, we almost always reason from inside to outside. When you see
we work out what is the type of x, what is the type of y, and whether the type of y is assignment compatible with x. But we do not use the fact that we know what the type of x is when we are working out the type of y.
That's because there might be more than one x:
We need to be able to work out the type of an expression without knowing what it is being assigned to. Type information flows out of an expression, not into an expression.
To work out the type of the conditional expression, we work out the type of the consequence and the alternative expressions, pick the more general of the two types, and that becomes the type of the conditional expression. So in your example, the type of the conditional expression is "int", and it is not a constant (unless the condition expression is constant true or constant false). Since it is not a constant, you can't assign it to byte; the compiler reasons solely from the types, not from the values, when the result is not a constant.
The exception to all these rules is lambda expressions, where type information does flow from the context into the lambda. Getting that logic right was very difficult.
我正在使用 VS 2005, for 并且我可以重现, for bool &布尔值,但不是 true
最简单的解决方法似乎是这种强制转换
所以,是的,三元运算符似乎导致常量将其类型“固定”为整数,并禁用隐式类型转换,否则您将从常量中获得隐式类型转换适合较小的类型。
I'm using VS 2005, for and I can reproduce, for bool & Boolean, but not for true
The simplest workaround seems to be this cast
So, yes, it seems that the ternary operator is causing the constants to "fix" their types as ints and disable the implicit type conversion that you would otherwise get from constants that fit within the smaller type.
我可能没有一个很好的答案给你,但如果你在很多地方这样做,你可以声明:
以及这些变量。如果
const
是项目本地的,那么您可能不会使用它。编辑:使用
readonly
是没有意义的 - 这些并不意味着要改变。I may not have a great answer for you, but if you do this in many places, you could declare:
and just these variables. You might get away with using
const
if it is local to the project.EDIT: using
readonly
would not make sense - these aren't ever meant to change.