我不明白C#编译器在下面的代码中如何在没有编译错误的情况下分配works
。此代码编译并正确运行,但worksUnchecked
的第二个赋值如果未放在unchecked
块中则不会编译。
var min = int.MinValue;
uint works = (uint)(min < 0 ? -min : min);
uint worksUnchecked = unchecked((uint)-int.MinValue);
为什么编译器允许从三元表达式中赋值?
答案 0 :(得分:3)
这与三元运算符本身并没有任何关系。相反,这是因为在三元运算符的上下文中,您在运行时转换变量值,而在uintMin2
的上下文中,您正在转换 literal 在编译时。
重要的是,默认的checked
/ unchecked
上下文在编译时与运行时不同。
默认情况下,如果表达式生成的值超出目标类型的范围,则仅包含常量值的表达式会导致编译器错误。如果表达式包含一个或多个非常量值,则编译器不会检测溢出
另一种说法是,默认情况下,如果编译器可以确定表达式超出范围,则会产生错误。如果它不能(在语言规范的规则中...它理论上 可以通过在编译时实际跟踪代码的执行而无关紧要),那么它就不会。
当然,可以更改这些默认值。正如您已经看到的,您可以应用unchecked
强制编译器在编译时忽略错误。您还可以使用/checked
compiler switch来控制编译时发生的情况。
答案 1 :(得分:0)
基于MSDN:
unchecked关键字用于抑制整数类算术运算和转换的溢出检查。
换句话说,在投放变量时,您的责任是转换时可能会丢失数据。如果要确保没有数据丢失或溢出,请使用checked keyword。
编译器允许您使用未经检查的语句,因为您正在转换相同的类型:
unchecked
{
uintMin2 = (uint)(-int.MinValue); //You are casting int.MinValue to uint that's why the compiler allows it.
}
答案 2 :(得分:-2)
无符号整数的范围从0到4,294,967,295。我不认为你可以将负数转换为无符号整数。
请参阅here。