C# 为什么我们需要静态私有数组来初始化其他非静态私有数组字段?

C# 为什么我们需要静态私有数组来初始化其他非静态私有数组字段?,c#,constructor,field,private-members,C#,Constructor,Field,Private Members,如果您查看.NET 4.0中的堆栈类,您会注意到有一个“emptyArray”私有静态字段,它在构造函数中用于初始化真正的“array”私有字段 private T[] array; private static T[] emptyArray; private int size; private int version; static Stack() { Stack<T>.emptyArray = new T[0]; } public Stack() { arra

如果您查看.NET 4.0中的
堆栈
类,您会注意到有一个“emptyArray”私有静态字段,它在构造函数中用于初始化真正的“array”私有字段

private T[] array;
private static T[] emptyArray;
private int size;
private int version;

static Stack()
{
    Stack<T>.emptyArray = new T[0];
}

public Stack()
{
    array = Stack<T>.emptyArray;
    size = 0;
    version = 0;
}
private T[]数组;
私有静态T[]空数组;
私有整数大小;
私有int版本;
静态堆栈()
{
Stack.emptyArray=newt[0];
}
公共堆栈()
{
数组=Stack.emptyArray;
尺寸=0;
版本=0;
}

为什么不干脆把
this.array=newt[0]?还有为什么在大小和版本字段中放置了初始化笔划,如果忽略这些行,它们将被初始化为默认值(0)。

这是因为,否则,每个
堆栈都会获得自己的
新T[0]
实例。现在它们都引用同一个实例:声明为静态的实例。假设您声明1000
堆栈
。它们都有一个对一个
字符串[0]
对象的引用。如果在构造函数中声明空数组,则会有1000个
字符串[0]
实例,每个
堆栈一个。所以这是出于性能原因


其他初始值设定项是不必要的,但是如果您使用Reflector查看其他源文件,您会发现到处都是相同的模式:具有默认值的字段在构造函数中被分配了显式值。

每个
堆栈
都已经获得了自己的
T[0]
当调用构造函数时,
array=Stack.emptyArray
,不是吗?不,它们会得到一个指向同一实例的引用(只有一个指针)。我认为这可能是一种编码约定,不依赖任何地方的默认值,而是将它们显式化。另一种可能是Reflector只是以这种方式显示,因为底层IL代码指定了显式的“默认”值。这意味着编译器将添加这些语句。最后,每个变量都应该有一个值,这样编译器就可以分配默认值。您可以通过编写一个不显式分配默认值的小类来测试它,编译它并在Reflector中打开它。空数组只有一种可想象的类型(出其不意,为空),因此出于性能原因,emptyArray是单例的。对于真、假、小整数也应该如此(至少在java中是<256左右)。这减少了内存使用。我刚刚编译了一个测试应用程序,在Reflector中打开了它。。默认值未在此处初始化。