为什么引用类型未初始化为null?

thi*_*eek 9 .net c# null initialization reference-type

检查此代码..

    string str;

    if (str.Contains("something.."))
    {
    }
Run Code Online (Sandbox Code Playgroud)

编译器会为此代码抛出此错误

使用未分配的局部变量'str'

为什么引用类型未初始化为null?

只想知道好奇心.

我也想知道下面的代码会发生什么.这项任务如何运作?

    string str = null;
Run Code Online (Sandbox Code Playgroud)

Meh*_*ari 22

仅自动初始化字段(在类级别声明的变量):

  • 值类型初始化为其默认值.
  • 引用类型初始化为null引用.

你声明的是方法中的"局部变量".无论是值类型还是引用类型,都不会自动初始化局部变量.

我也想知道下面的代码会发生什么.这项任务如何运作?

这个赋值使用一个ldnull指令后跟一条stloc指令初始化具有空值的局部变量(当然它没有被优化),更重要的是,满足编译器的数据流分析规则以进行明确的赋值.C#规范定义了一个名为明确赋值的概念,它确保在首次使用之前分配变量.

  • @Mehrdad:我想他想知道为什么局部变量不会自动初始化为默认值而不是字段.原因是因为这已经是一种优化.编译器可以安全地说明是否为本地变量赋值.如果不是,编译器将在编译时抛出错误.对于字段,这种优化是不可能的. (2认同)

Eri*_*ert 7

C#语言要求在读取所有变量之前明确赋值.局部变量被认为最初是未分配的,而字段,数组元素等被认为最初被分配给它们的默认值.(对于引用类型,该值为null.)

没有技术原因可以解释为什么我们不能将局部变量视为最初分配给它们的默认值并丢弃所有明确的赋值检查.它就在那里,因为使用未分配的局部作为其默认值是(1)不良编码实践,以及(2)极有可能的刺激性错误来源.通过要求您在使用之前显式分配局部变量,我们会阻止用户使用不良操作,并消除您从未调试过的整类错误.

另外,请考虑以下事项:

while(whatever)
{
    int i;
    print(i);
    i = i + 1;
}
Run Code Online (Sandbox Code Playgroud)

你是否希望我在循环的执行中保持其值,或者每次都将其初始化为零?通过强制你明确地初始化它,问题变得毫无意义,这是一个没有区别的差异.

(另外,在上面的例子中,有一个很小的潜在性能优化,因为编译器可以重新使用变量而不必生成代码来清除其内容,因为编译器知道将清除内容.)

我不知道如何回答你的第二个问题,因为我不知道你的"工作"是什么意思.你能告诉我怎么分配"int x = 123;" 作品?一旦我知道"作品"的含义,我就可以描述如何将null赋给引用类型的变量.