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

发布于 2024-08-17 10:59:59 字数 345 浏览 4 评论 0原文

检查此代码。

    string str;

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

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

使用未分配的局部变量“str”

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

只是出于好奇而想知道。

我还想知道下面的代码会发生什么。这项作业如何进行?

    string str = null;

Check this code..

    string str;

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

Compiler throws this error for this code

Use of unassigned local variable 'str'

Why does a reference type is not initialized to null ?

Just want to know out of curiosity.

I'd also want to know what happens for code below. how does this assignment work ?

    string str = null;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

如日中天 2024-08-24 11:00:00

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

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

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

我还想知道下面的代码会发生什么。这项作业如何进行?

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

Only fields (variables declared at class level) are initialized automatically:

  • Value types are initialized to their default value.
  • Reference types are initialized to null reference.

What you are declaring is a "local variable" inside a method. Local variables are not automatically initialized regardless of being a value type or reference type.

I'd also want to know what happens for code below. how does this assignment work ?

This assignment initializes the local variable with null value with an ldnull instruction followed by a stloc instruction (in case it's not optimized out, of course) and more importantly, satisfies the compiler's data flow analysis rules for definite assignment. C# specification defines a concept called definite assignment that ensures a variable is assigned before first use.

三生殊途 2024-08-24 11:00:00

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

没有任何技术原因可以解释为什么我们不能将局部变量视为最初分配给它们的默认值并放弃所有明确的赋值检查。它之所以存在,是因为使用未分配的本地作为其默认值是(1)一种糟糕的编码实践,(2)很可能是令人恼火的错误的来源。通过要求您在使用局部变量之前显式分配它们,我们可以防止用户使用不好的做法,并消除一整类您永远不必调试的错误。

另外,请考虑以下问题:

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

您是否希望 i 在循环执行过程中保持其值,或者每次都将其初始化为零?通过强迫您显式初始化它,问题变得毫无意义,这是一个没有区别的区别。

(此外,在上面的情况下,还有一个小的潜在性能优化,因为编译器可以重新使用该变量,而无需生成代码来清除其内容,因为编译器知道将清除该变量内容。)

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

The C# langauge requires that all variables be definitely assigned to before they are read from. Local variables are considered to be initially unassigned, whereas fields, array elements, and so on, are considered to be initially assigned to their default value. (Which, for a reference type, is null.)

There is no technical reason why we couldn't treat local variables as initially assigned to their default values and throw away all the definite assignment checking. It's there because using an unassigned local as its default value is (1) a bad coding practice, and (2) a highly probable source of irritating bugs. By requiring you to explicitly assign local variables before they are used, we prevent the user from using a bad practice, and eliminate a whole class of bugs that you then never have to debug.

Also, consider the following:

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

Do you expect i to hold its value across executions of the loop, or for it to be initialized fresh to zero every time? By forcing you to explicitly initialize it, the question becomes meaningless and this is a difference which makes no difference.

(Also, in the case above there is a small potential performance optimization, in that the compiler could re-use the variable without having to generate code to clear its contents because the compiler knows that you will clear the contents.)

I don't know how to answer your second question because I don't know what you mean by "work". Can you tell me how assigning "int x = 123;" works? Once I know what you mean by "works" then I can describe how assigning a null to a variable of reference type works.

阳光的暖冬 2024-08-24 11:00:00

确实被初始化为null。编译器只是帮了你一个忙,因为你不必调试不可避免的 NullReferenceException。

It does get initialized to null. The compiler just did you a favor by not having to debug the inevitable NullReferenceException you'll get.

心欲静而疯不止 2024-08-24 11:00:00

还要记住,对空字符串调用 Contains 将引发 NullReferenceException。

Keep in mind as well that calling Contains on a null string will throw a NullReferenceException.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文