如何使用三元表达式来解决溢出编译错误

时间:2017-03-10 00:00:52

标签: c# casting compilation

我不明白C#编译器在下面的代码中如何在没有编译错误的情况下分配works。此代码编译并正确运行,但worksUnchecked的第二个赋值如果未放在unchecked块中则不会编译。

var min = int.MinValue;
uint works = (uint)(min < 0 ? -min : min);
uint worksUnchecked = unchecked((uint)-int.MinValue);

为什么编译器允许从三元表达式中赋值?

3 个答案:

答案 0 :(得分:3)

这与三元运算符本身并没有任何关系。相反,这是因为在三元运算符的上下文中,您在运行时转换变量值,而在uintMin2的上下文中,您正在转换 literal 在编译时。

重要的是,默认的checked / unchecked上下文在编译时与运行时不同。

来自the documentation

  

默认情况下,如果表达式生成的值超出目标类型的范围,则仅包含常量值的表达式会导致编译器错误。如果表达式包含一个或多个非常量值,则编译器不会检测溢出

另一种说法是,默认情况下,如果编译器可以确定表达式超出范围,则会产生错误。如果它不能(在语言规范的规则中...它理论上 可以通过在编译时实际跟踪代码的执行而无关紧要),那么它就不会。

当然,可以更改这些默认值。正如您已经看到的,您可以应用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