C# 为什么我们需要静态私有数组来初始化其他非静态私有数组字段?
如果您查看.NET 4.0中的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
堆栈类,您会注意到有一个“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中打开了它。。默认值未在此处初始化。