这不过是 C # 语言的一个设计决策,如 由 Eric Lippert 解释。CLR 和。NET 环境不需要它。例如,使用未初始化的本地变量,VB.NET 就可以很好地进行编译,而实际上,CLR 将所有未初始化的变量初始化为默认值。
同样的情况也可能发生在 C # 上,但是语言设计人员选择不这样做。原因是初始化的变量是错误的巨大来源,因此,通过强制初始化,编译器有助于减少意外错误。
为什么字段不需要初始化?
那么,为什么这种强制的显式初始化不会发生在类中的字段中呢?仅仅因为显式的初始化可能在构造期间发生,通过对象初始化程序调用的属性,甚至在事件发生很久之后调用的方法。编译器不能使用静态分析来确定是否每个可能的路径通过代码导致变量被显式地初始化在我们之前。如果出现错误就会很烦人,因为开发人员可能会得到无法编译的有效代码。所以 C # 根本不会强制执行它,如果没有显式设置,CLR 会自动将字段初始化为默认值。
那收集类型呢?
C # 对本地变量初始化的执行是有限的,这经常会让开发人员措手不及:
string str;
var len1 = str.Length;
var array = new string[10];
var len2 = array[0].Length;
// Library written by BarCorp
public abstract class Bar
{
// Derived class is responsible for initializing x.
protected int x;
protected abstract void InitializeX();
public void M()
{
InitializeX();
Console.WriteLine(x);
}
}
编译这个库是一个错误吗?如果是的话,巴克公司该如何修复漏洞?通过给 x 赋一个默认值?但编译器已经这么做了。
假设这个库是合法的,如果 FooCorp 写
public class Foo : Bar
{
protected override void InitializeX() { }
}