struct SomeValue { public Int32 x; }
//SomeVal v1 = new SomeVal();  //分配在堆栈上
SomeVal v1;                   //分配在堆栈上(与上面语句对比)
该行代码也会产生将实例分配在线程堆栈上,并将其所有字段置0的IL指令。两者唯一的差别是如果我么使用了new操作符,那么C#将认为实例已经得到了初始化。
又,
SomeVal v1;
Int32 a = v1.x;//无法通过编译:使用了可能未赋值的字段"x"
---------------------------------------------------------------------
上面这些是我从《.net框架程序设计》137-138页截取下来的(个人省略了一些东西,但基本意思霉变)。
我有一点很不理解:既然“SomeVal v1;”也会产生将实例分配在线程堆栈上,并将其所有字段置0的IL指令,那C#为什么还会认为这种情况下v1没有初始化呢?“将实例分配在线程堆栈上,并将其所有字段置0的IL指令”不正是C#编译器产生的么?既然它自己(C#编译器)产生了这些“清0”指令,那么它就应该认为v1是已经初始化的,进而使“Int32 a = v1.x;”能够顺利编译!但是现实却是:它自己(C#编译器)产生了这些“清0”指令,却又说v1没有赋值,而不让“Int32 a = v1.x;”通过编译!!这不是自相矛盾么?
望高手给解释一下,谢谢。

解决方案 »

  1.   

    SomeVal v1;其未实例化,仍指向一个空引用,即null.在未实例化的时候调用会产生空引用异常
      

  2.   

    to zhgroup(王员外):  SomeVal是struct,是值类型,不是引用类型。  请认真看题目。
      

  3.   

    IL置0只是二进制含义上的,不是真正的0可能是编译器必须要你用new吧,不然的话,就不是C#了
      

  4.   

    内存的空间分配不等于变量的真正初始化,你的问题真正所在不是x的问题,而是v1未被初始化。
    这是C#的特有编译检查,即所有类型在使用之前都必须初始化。
    所以你必须通过new或者其他方式给v1进行初始化,这样才能访问其成员。
      

  5.   

    to Knight94(愚翁):
       个人感觉奇怪,既然“C#编译器不new就不通过编译”,那么
    ---------------------------------------------------------------------
    SomeVal v1;                   //分配在堆栈上(与上面语句对比)
    该行代码也会产生将实例分配在线程堆栈上,并将其所有字段置0的IL指令。
    ---------------------------------------------------------------------
    这段话是什么意思呢?编译都没通过,还产生什么指令啊?
      

  6.   

    SomeVal v1; //置0
    v1 = new SomeVal(); //初始化