Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么?:导致转换错误,而if-else没有?_C#_.net_Type Conversion - Fatal编程技术网

C# 为什么?:导致转换错误,而if-else没有?

C# 为什么?:导致转换错误,而if-else没有?,c#,.net,type-conversion,C#,.net,Type Conversion,在代码中做一些更改我使用下一行: uint a = b == c ? 0 : 1; Visual Studio向我显示此错误: 无法将类型“int”隐式转换为“uint”。存在显式转换(是否缺少强制转换?) 但如果我使用代码: uint a; if (b == c) a = 0; else a = 1; 它工作正常,没有任何错误或警告。为什么?您应该使用以下命令使代码正常工作: uint a = b == c ? 0U : 1U; 为什么我不能使用uint a=b

在代码中做一些更改我使用下一行:

uint a = b == c ? 0 : 1;
Visual Studio向我显示此错误:

无法将类型“int”隐式转换为“uint”。存在显式转换(是否缺少强制转换?)

但如果我使用代码:

uint a; 

if (b == c) 
    a = 0; 
else 
    a = 1;
它工作正常,没有任何错误或警告。为什么?

您应该使用以下命令使代码正常工作:

uint a = b == c ? 0U : 1U;
为什么我不能使用
uint a=b==c?0 : 1;

表达式的类型
b==c?0:1是
int
。如中所示,没有从
int
uint
的隐式转换,因此这是不允许的

为什么我可以使用
a=0

因为当值是常量表达式时,会对数值类型进行特殊处理

根据C#规范第6.1.9节:

  • int类型的常量表达式可以转换为sbyte、byte、short、ushort、uint或ulong类型,前提是常量表达式的值在目标类型的范围内

  • long类型的常量表达式可以转换为ulong类型,前提是常量表达式的值不是负值

如第一个项目符号所示,
a=0
a=1
都是允许的,因为
0
1
是常量表达式,并且是有效的
uint
值。基本上,这归结为编译器可以在编译时轻松确定这些转换是否有效,因此它允许它们


顺便说一句,如果第一个示例的
b==c
部分更改为常量表达式(例如
true
),然后整个条件运算符表达式将是一个常量表达式,代码将编译。

如果
b==c
是一个常量表达式,那么整个条件运算符将被视为一个常量表达式,因此,允许将
int
类型的常量表达式转换为其他int类型的规则将适用,并且它将编译

显然,
b==c
不是一个常量表达式,因此在运行时之前无法知道条件运算符的结果,因此允许将int隐式转换为uint(对于常量表达式)的豁免不适用


if
/
else
变量中,两个实际赋值都是常量表达式。

(b==c)?0U:1U
可以工作。这是由于将整数文本直接赋给变量时发生的隐式转换。但当您使用三元运算符时,编译器不进行隐式转换,只检查两个分支是否可以转换为同一类型。避免此问题的更好方法是首先不使用uint。你为什么要用uint?这在C#中是一种糟糕的代码味道。uint是为了与使用uint的C和COM库的互操作性而存在的。@JakeMillington:此外,如果你的数量经常超过20亿,那就看在上帝的份上使用long。你真的想花一分钟来调试这个问题吗?当你认为永远不到40亿的数量突然变成50亿的时候,uint就结束了?杰克·米林顿:等等,还有更多。假设我们有两个量,它们在逻辑上从不为负。比如说,字符串的大小。好的,我这么说:
string.Length
现在是
uint
。现在请为我正确地编写代码,它包含两个字符串,并给出它们长度的差异。您认为有多少次会忘记将强制转换添加到int?您认为这个bug需要多长时间才能导致严重故障?现在我们有了一个程序,它在市场上的失败是由于使用了uint!UINT与我们日常工作的数学域不匹配。@JakeMillington:A长是八个字节。整数是四。您至少有20亿字节的地址空间。你有超过一亿的钱吗?如果是这样,那就开始担心吧。你是一个记忆亿万富翁;不用担心便士。这是可行的,但它不能回答OP的问题。这就解释了为什么
uint a=true?0:1不编译。要点是隐式转换只适用于常量表达式。@haim770-这就是我决定回答的原因。格罗的评论虽然基本上是充分的,但暗示条件运算符永远不会允许这种情况发生。