为什么C#三元运算符似乎改变了返回值的类型? [英] Why does the C# ternary operator appear to change the type of returned values?
问题描述
我有以下 if()
声明:
I have the following if()
statement:
if( _hexColourString.Length >= 8 )
_bytes[ 3 ] = byte.Parse( _hexColourString.Substring( start + 6, 2 ), NumberStyles.AllowHexSpecifier );
else
_bytes[ 3 ] = 0x00;
如果我尝试使用三元运算符来表达这一点,我会收到错误消息,说我无法隐式转换 int
到字节
。以下不编译:
If I try to express this using the ternary operator, I get an error saying I cannot implicitly convert an int
to a byte
. The following does NOT compile:
_bytes[ 3 ] = ( _hexColourString.Length >= 8 ) ? byte.Parse( _hexColourString.Substring( start + 6, 2 ), NumberStyles.AllowHexSpecifier ) : 0x00;
所以我想我会检查三分配的哪一半给出了问题。我取出了声明的条件部分并将两个作业写成单独的声明,如下所示:
So I thought I'd check which half of the ternary assignment was giving the problem. I took out the conditional part of the statement and wrote the two assignments as separate statements, like this:
_bytes[ 3 ] = byte.Parse( _hexColourString.Substring( start + 6, 2 ), NumberStyles.AllowHexSpecifier );
_bytes[ 3 ] = 0x00;
这两个编译。三元运算符似乎正在改变其中一个赋值的隐式类型(文字 0x00
)。
为什么普通赋值 _bytes [3] = 0x00;
编译没有强制转换但是当表达式是三元运算符的一部分时需要一个?
我尝试了什么:
作为最后的理智检查,我想最终确定哪一方任务导致了问题。我怀疑字面的十六进制字节,我似乎是正确的。以下无意义的语句编译:
Both of these compile. The ternary operator seems to be changing the implicit type of one of the assignments (the literal 0x00
).
Why does the plain assignment _bytes[ 3 ] = 0x00;
compile okay without a cast but requires one when the expression is part of a ternary operator?
What I have tried:
As a final sanity check, I wanted to see conclusively which side of the assignment was causing the problem. I suspected the literal hex byte and I appear to be correct. The following pointless statement compiles:
_bytes[ 3 ] = ( _hexColourString.Length >= 8 ) ? byte.Parse( _hexColourString.Substring( start + 6, 2 ), NumberStyles.AllowHexSpecifier ) :
byte.Parse( _hexColourString.Substring( start + 6, 2 ), NumberStyles.AllowHexSpecifier );
但以下同样无意义的陈述不编译:
But the following equally pointless statement does NOT compile:
_bytes[ 3 ] = ( _hexColourString.Length >= 8 ) ? 0x00 : 0x00;
推荐答案
只需0
Try just "0"
_bytes[ 3 ] = ( _hexColourString.Length >= 8 ) ? byte.Parse( _hexColourString.Substring( start + 6, 2 ), NumberStyles.AllowHexSpecifier ) : 0;
或显式演员< br $>
Or an explicit cast
_bytes[ 3 ] = ( _hexColourString.Length >= 8 ) ? byte.Parse( _hexColourString.Substring( start + 6, 2 ), NumberStyles.AllowHexSpecifier ) : (byte)0;
我想我的问题应该是为什么普通的赋值(_bytes [3] = 0x00;)在没有强制转换的情况下编译好但是当表达式是部分时需要一个一个三元运算符?
I guess my question should really have been why does the plain assignment (_bytes[ 3 ] = 0x00;) compile okay without a cast but requires one when the expression is part of a ternary operator?
因为编译器可以从上下文告诉常量值应该是一个字节,而不是一个int。
当你创建一个但是三元运算,编译器可以选择:
Because the compiler can tell from the context that the constant value should be a byte, not an int.
When you create a ternary operation though, the compiler has a choice:
byte b = 100;
byte c = (a ? b : 0)
可能可以通过两种方式看到:
Could be seen in two ways:
byte b = 100;
byte c = (a ? b : (byte) 0)
或
Or
byte b = 100;
byte c = (a ? (int) b : 0)
它会选择第二个,因为整数是更常见和自然的单位。
然后它抱怨,因为从int到所需的字节的隐式转换可能会丢弃信息。 (并不是说有任何东西可以扔掉,但是嘿 - 编译器编写者无法想到一切!)
And it will pick the second because integers are the more common and "natural" unit.
Then it complains because the implicit cast from a int to a byte needed could potentially throw away information. (Not that there is any to throw away, but hey - compiler writers can't think of everything!)
除了其他两个解决方案(和评论)之外我发现这相当不错Eric Lippert的解释...... 为什么我是否必须在三元表达式中对int进行类型转换? [ ^ ]
In addition to the other two solutions (and comments) I found this quite good explanation from Eric Lippert ... Why do I have to typecast an int in a ternary expression?[^]
这篇关于为什么C#三元运算符似乎改变了返回值的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!