【问题标题】:Different types evaluated for keyword var为关键字 var 评估的不同类型
【发布时间】:2015-09-14 02:43:52
【问题描述】:

我有以下 2 块代码,旨在推断编译器分配给 var 关键字的类型。

var b = 0x80000000 - 0x1;
Console.WriteLine("b: {0}", b);
Console.WriteLine("b.GetType()={0}", b.GetType());

uint val1 = 0x80000000;
int val2 = 0x1;
var c = val1 - val2;
Console.WriteLine("c: {0}", c);
Console.WriteLine("c.GetType(): {0}", c.GetType());

输出:

  b: 2147483647                   //Result of UInt32-Int32
                                  //(as compiler assigns datatype in the
                                  //order of int, uint, long and ulong)
  b.GetType()=System.UInt32       //OK

  c: 2147483647                   //Uint32-Int32                               
  c.GetType(): System.Int64       //Not Understood, why not UInt32 ?

如果var bvar c 具有几乎相同的初始化——var c 甚至是显式的,那么为什么它会给出意外的数据类型 System.Int64?

【问题讨论】:

  • 如果你从一个无符号整数中减去一个有符号整数,那么你必须考虑结果将被签名的可能性。您还必须考虑结果大于Int32 的可能性。那么你有什么选择呢?提示:Int64 将是唯一可以处理 val1 - val2 的所有可能值的类型。
  • @MattBurland:是的,没错!但是为什么编译器在var b 期间没有“思考”这个问题
  • 请注意, var b 可以在编译期间计算,等式甚至不会进入代码。它与 var c 的作用不同,后者作用于将其纳入编译代码的变量。
  • @NirajDoshi:因为在第一种情况下,您要减去两个 literals。它们是恒定的。结果可以在编译时计算出来。

标签: c# .net types var


【解决方案1】:

因为

var b = 0x80000000 - 0x1;

已经计算过了。通过优化

但是

var val1 = 0x80000000;
var val2 = 0x1;
var c = val1 - val2;

尚未计算。并且编译器猜测val1val2 可能会在以后更改...

const uint val1 = 0x80000000;
const int val2 = 0x1;
var c = val1 - val2;

c 现在是 UInt32,因为编译器会计算它并知道结果。

因为val1val2 是常量,并且编译器知道它们不会被更改。所以不再需要Int64

【讨论】:

  • 如果您确定它是在编译期间计算的,我必须接受它作为答案。你能提供一个进一步的阅读链接吗?谢谢
  • here@NirajDoshi
【解决方案2】:

问题在于,当您在intuint 之间进行运算时,uint 被转换为有符号数。

因此,为了 uint 能够将其所有信息(从 0 到 23 - 1)存储在无符号数中,它必须转换为 long(从-263 到 263 - 1),因为 int 的范围是从 -231 到 231 - 1.

【讨论】:

    【解决方案3】:

    编译器自动将类型扩展为 64 位,因为这是唯一可以保存 UInt32Int32 之间运算结果的整数。尝试更改为

    ulong val1 = 0x80000000;
    long val2 = 0x1;
    

    你会看到一个编译错误,因为编译器找不到保存结果的类型。

    Int64 不是b 的推断类型,因为编译器检测到常量落入Int32 范围。试试

    var b = 0x800000000000 - 0x1;
    

    你会看到推断类型long

    【讨论】:

    • 但是对于代码的var b 部分也是如此。
    • 编辑 (0x80000000000) 后,这很明显,因为您正在执行 Int64-Int32
    猜你喜欢
    • 2011-04-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-02
    • 1970-01-01
    • 2020-07-08
    • 1970-01-01
    相关资源
    最近更新 更多