为什么一个可以编译而另一个不能编译?

时间:2020-06-03 16:24:33

标签: c# visual-studio

由于溢出,无法编译此代码:

byte number = 1000;
Console.WriteLine(number);

但是由于与溢出相同的原因,该值的值为1

byte number = 255;

number += 2;

Console.WriteLine(number);

我的问题是,为什么第一个示例给出错误而第二个示例不会给出错误?

4 个答案:

答案 0 :(得分:1)

Range of byte type is 0 to 255

在第一个示例中,当您分配number = 1000时,它超出了字节范围的限制,并给出了编译时错误。

在第二个示例中,您要分配number = 255,因为255在字节范围内。当您将2添加到最大字节数限制即255时,它从0开始并打印1作为结果

答案 1 :(得分:1)

第一个不会编译,因为无法将byte设置为1000。第二个之所以能够编译,是因为可以将byte 设置为255,并且因为在执行超出其范围的算术运算时该值会溢出。

在第二个示例中,您都不会尝试将byte设置为1000。第二个示例中出现的每个操作都是有效的。但是第一个示例中的一个操作无效。

基本上,编译器不会尝试为您计算溢出。运行时将处理溢出。

答案 2 :(得分:0)

byte是8位,并且可以关闭。用数学表示,它是0或1,分别是on和off。

因此,如果您连续放置8位,则可以开始用二进制表示数字:

00000000 = 0
00000001 = 1
00000010 = 2
...
11111111 = 255

正如其他人所指出的,当您将2加到255时,它溢出并回绕:

 11111111 (255)
+00000010 (2)
---------------
 00000001 (1)

您需要一个更大的原语(至少具有10位)来表示1000之类的数字,并且您的编译器知道这一点并试图警告您。

答案 3 :(得分:0)

差异归因于the rules surrounding C#'s checked and unchecked contexts

  • 恒定值(使用C#规范的良好定义的规则,编译器可以在编译时确定的常数)默认为checked。尝试为数字类型分配超出范围的值(在您的情况下,将1000分配给范围为byte的{​​{1}})将导致编译时错误。您可以通过将表达式包装在[0,255]上下文中来抑制这种情况。

    unchecked

    得出byte number = unchecked((byte) 1000); Console.WriteLine(number);

  • 非恒定值-即在运行时计算的值-默认为232。这允许发生上溢/下溢。 This blog post explains the rationale for choosing unchecked as the default.您可以选​​择制作一个表达式或块unchecked,如果发生上溢/下溢,会导致运行时性能稍有下降,使运行时抛出异常。

    checked

    通过checked { byte number = 255; number += 2; Console.WriteLine(number); } 操作将System.OverflowException抛出行。

    或者,您可以将the -checked compiler flag的默认位置设置为+=,但标记为checked的地方除外。