views:

39

answers:

1

If you take a look inside Stack<T> class from .NET 4.0, you will notice that there is an "emptyArray" private static field which is used inside constructors to initialize a real "array" private field.

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;
}

Why not just put this.array = new T[0]; ? And also why there are placed initialization strokes for size and version fields, if you omit those lines they will be initialied to default values (0) anyway.

+1  A: 

That's because otherwise, every Stack gets his own instance of a new T[0]. Now they all refer to the same instance: the one that's declared static. Suppose you declare 1000 Stack<string>. These all have a reference to one string[0] object. If you declared the empty array inside the constructor, you would have a 1000 string[0] instances, one for each Stack<string>. So it's for performance reasons.

The other initializers are unnecessary but if you take a look with Reflector through other source files, you see the same pattern everywhere: fields with default values are assigned explicit values inside a constructor.

Ronald Wildenberg
Every `Stack` is already getting his own `T[0]` when constructor is called `array = Stack<T>.emptyArray`, isn't it?
Grief Coder
No, they get a reference (only a pointer) to the same instance.
Ronald Wildenberg
I see this pattern, the question is Why it's coded this way?
Grief Coder
Right, I forgot that T[] is a reference type..
Grief Coder
I think it may be a coding convention not to depend on default values anywhere but to make them explicit. Another possibility is that Reflector simply shows it this way because the underlying IL code assigns explicit 'default' values. That would mean that the compiler adds these statements. In the end every variable should have a value so it could be the compiler's job to assign default values. You could test this by writing a small class that doesn't explicitly assign default values, compile it and open it inside Reflector.
Ronald Wildenberg
No, every stack gets a _reference_ to this single version of an empty array. Theres only one thinkable type of an empty array<T> (which is, surprise, empty), so emptyArray is a singleton due to performance reasons. Same should go for true, false, small integers (at least in java its < 256 or so). This reduces memory usage.
atamanroman
fielding, that makes sense, thanks for commenting.
Grief Coder
I've just compiled a testing app, opened it in Reflector.. default values are not initialized there.
Grief Coder
Interesting. In that case I think it's a coding convention at Microsoft. It makes some sense, you can never be mistaken about the value of a variable. But I'm not 100% sure about this..
Ronald Wildenberg