我为什么要明确地围绕"未选中"?

Mar*_*ari 10 c# casting unchecked

有没有人能够解释我这种奇怪的行为?

    int i = 0x1234;
    byte b1 = (byte)i;
    byte b2 = (byte)0x1234;         //error: const value '4660' can't convert to byte (use unchecked)
    byte b3 = unchecked((byte)0x1234);
    byte b4 = checked((byte)i);     //throws
    byte b5 = (byte)(int)0x1234;    //error: same as above
Run Code Online (Sandbox Code Playgroud)

注意:它是一个空的控制台应用程序,没有启用算术检查(默认情况下).提前谢谢大家.

编辑:我应该足够清楚,但不是所有人.

我知道一个单词不能适合一个字节.但是,默认情况下,C#程序允许某些"危险"操作,主要是出于性能原因.

类似地,我可以将两个大整数相加并且根本没有溢出.

我的奇怪是关于上面的编译时错误:编译b1强制转换/赋值,b2无法编译.显然没有区别,因为两者都是Int32具有相同的值.

希望现在很清楚.

Jon*_*eet 13

你绊倒了C#4规范第7.19节的一部分:

除非在unchecked上下文中显式放置常量表达式,否则在表达式的编译时求值期间,在整型算术运算和转换中发生的溢出总是会导致编译时错误.

基本上,关键在于即使您很乐意在执行时允许操作溢出,如果您尝试使用在编译时无法转换为目标类型的常量表达式,您必须告诉编译器,你真的知道你在做什么.

例如,在这种情况下,您将丢失信息 - 它将等同于

byte b3 = 0x34;
Run Code Online (Sandbox Code Playgroud)

所以你通常最好只指定一下,为你提供更清晰的代码,不会误导读者.你想要在常量中溢出是相对罕见的 - 大多数时候你应该只指定有效值.

  • 你听起来像一个律师引用了"C#4规范的第7.19节_".:d (3认同)
  • @Leito:我不介意成为语言律师 - 规范(在某种程度上,无论如何)是语言的真正权威,因此在尝试证明编译器行为IMO时,给出规范参考是一种很好的做法. (2认同)