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

时间:2010-01-06 13:32:14

标签: c# .net null initialization reference-type

检查此代码..

    string str;

    if (str.Contains("something.."))
    {
    }

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

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

  

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

只是想出于好奇而知道。

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

    string str = null;

4 个答案:

答案 0 :(得分:22)

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

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

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

  

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

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

答案 1 :(得分:7)

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

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

另外,请考虑以下事项:

while(whatever)
{
    int i;
    print(i);
    i = i + 1;
}

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

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

我不知道如何回答你的第二个问题,因为我不知道你的“工作”是什么意思。你能告诉我怎么分配“int x = 123;”作品?一旦我知道“作品”的意思,那么我就可以描述如何为参考类型的变量赋值。

答案 2 :(得分:2)

初始化为null。编译器只是帮你调试你不必要的NullReferenceException。

答案 3 :(得分:-1)

请记住,在空字符串上调用Contains会抛出NullReferenceException。