为什么未自动初始化未分配的局部变量?

Joa*_*nge 10 .net c# compiler-construction variables initialization

似乎没有办法在代码中使用未分配的局部变量或检查它们,因为编译器会发出Use of unassigned local variable错误.

为什么编译器default(T)在编译时不使用这些变量?

即使对值类型更难做,null在这种情况下,引用类型也可以很容易地初始化,对吧?

这是一些测试代码:

public void Test ( )
{
    int x;
    string s;

    if ( x == 5 )
        Console.WriteLine ( 5 );

    if ( s != null )
        Console.WriteLine ( "s" );
}
Run Code Online (Sandbox Code Playgroud)

返回:

Use of unassigned local variable 'x'
Use of unassigned local variable 's'
Run Code Online (Sandbox Code Playgroud)

更新:

对于声称这是不允许有充分理由的人,为什么允许在课堂上?

public class C
{
    public int X;
    public string S;

    public void Print ( )
    {
        Console.WriteLine ( X );
        Console.WriteLine ( S );
    }
}
Run Code Online (Sandbox Code Playgroud)

这段代码编译得很好.

为什么在类级别而不是在方法级别上没有问题?

Ant*_*ram 6

C#是一个"成功的坑"语言.

这是一个设计决策,因为该语言完全能够允许您使用未明确分配的本地.但是,通常情况下,这些变量的使用是错误的,代码路径由于某种原因没有设置值.为避免此类错误,编译器要求在使用之前分配所有本地.


Chr*_*ens 6

我看到你已经更新了你的问题,所以我会更新我的答案.你的问题有两部分,一部分涉及local variables另一部分instance variables on a class instance.然而,首先,这不是编译器设计决策,而是语言设计决策.

规范第12.3.1/12.3.2节

局部变量

我们知道为什么你可以定义一个变量而不给它一个值.一个原因,这样的例子:

int x;
// do stuff
x = 5;  // Wow, I can initialize it later!
Console.WriteLine(x);
Run Code Online (Sandbox Code Playgroud)

该标准定义了这是有效代码的原因.现在,我不是在C#设计团队中,但很有道理他们不会为你自动初始化代码(除了你实际上希望它自动初始化时的性能影响).

说上面的代码是你的意图,但你忘了初始化x = 5;.如果编译器已经为你自动初始化了变量,那么代码就会被编译,但它会像你期望的那样做.

虽然这是一个微不足道的例子,但这是语言设计师的一个非常好的设计决定,因为它可以避免许多令人头疼的问题,试图弄清楚为什么某些东西没有按预期工作.

作为旁注,我想不出你为什么要在没有分配内容的情况下定义代码的原因,或者使用默认值(在每种情况下),对我来说可能是一个bug,我就是确定编译器设计者可能已经确定了什么.

类实例变量

类级别成员由最初分配的标准定义.事实上,为了公平起见,这些外面的局部变量的声明catch,foreachusing声明的最初分配.实际上,这是一个标准问题,而不是编译器问题.

如果我试图猜测为什么这是关于类实例的实例变量的情况,我会说它与如何在堆上分配内存有关,因为那是分配类的地方.在堆上分配类时,必须初始化所有成员并在堆上分配它.在类成员而不是局部变量中执行它不仅可以,它必须以这种方式完成.它们根本不能被取消分配.


Hen*_*man 5

1为什么编译器不允许使用未初始化的变量?

因为防止促进良好的编程.

2为什么编译器允许使用未初始化的类成员?

因为无法准确跟踪这一点.


Dav*_*ras -1

因为你想要里面有什么?你希望 x 默认为零,而我希望它默认为 5...

如果他们将 0 分配给 int(s) 并且全世界都开始假设如此,那么它们将在某个时候更改为 -1,这将破坏全球许多应用程序。

我认为在 VB6 中,默认情况下变量被分配给某些东西,但它并不像看起来那么好。

当您使用 C# 或 C++ 时,您可以根据需要分配值,而不是编译器为您分配的值。