I found a while ago (and I want to confirm again) that if you declare a class level variable, you should not call its constructor until the class constructor or load has been called. The reason was performance - but are there other reasons to do or not do this? Are there exceptions to this rule?

12 Answers
12

If you set your variable outside of the constructor then there is no error handling (handeling) available. While in your example it makes no difference, but there are many cases that you may want to have some sort of error handling. In that case using your first option would be correct.

Nescio talked about what implication this would have on your applicaiton if there were some constructor failures.

I believe initializing your members variables inside the constructor is subject to race conditions when threading is used, while initializing at declaration is ran as atomic operation.
–
HaoestOct 29 '08 at 21:59

Honestly, if you look at the IL, all that happens in the second case is the compiler moves the initialization to the constructor for you.

Personally, I like to see all initialization done in the constructor. If I'm working on a throwaway prototype project, I don't mind having the initialization and declaration in the same spot, but for my "I want to keep this" projects I do it all in the constructor.

Actually, in spite of what others have said, it can be important whether your initialization is inside or outside the constructor, as there is different behaviour during object construction if the object is in a hierarchy (i.e. the order in which things get run is different).

See this post and this post from Eric Lippert which explains the semantic difference between the two in more detail.

So the answer is that in the majority of cases it doesn't make any difference, and it certainly doesn't make any difference in terms of performance, but in a minority of cases it could make a difference, and you should know why, and make a decision based on that.

There's a common pattern called Dependency Injection or Inversion of Control (IOC) that offers exactly these two mechanisms for "injecting" a dependant object (like a DAL class) into a class that's furthur up the dependency chain (furthur from the database)

In this pattern, using a ctor, you would

public class SomeClass
{
private PersonObject per;

public SomeClass(PersonObject person)
{
per = person;
}

}

private PersonObject Joe = new PersonObject("Smitface");

SomeClass MyObj = new SomeClass(Joe);

Now you could for example, pass in a real DAL class for production call
or a test DAL class in a unit test method...

It depends on the context of how the variable will be used. Naturally constants and static or readonly should be initialized on declaration, otherwise they typically should be initialized in the constructor. That way you can swap out design patterns for how your objects are instatiated fairly easy without having to worry about when the variables will be initialized.

you could never make assumptions looking at the constructor alone because the language allows you to do it another way. what if you import some code you wrote last year the other way? hope you don't switch patterns. (in this case it seems the generated IL is equivalent, but there could be other)
–
Dustin GetzOct 29 '08 at 18:42

You should generally prefer the second variant. It's more robust to changes in your code. Suppose you add a constructor. Now you have to remember to initialize your variables there as well, unless you use the second variant.

Of course, this only counts if there are no compelling reasons to use in-constructor initialization (as mentioned by discorax).

The first declaration is actually cleaner. The second conceals the fact the constructor initializes the class in the static constructor. If for any reason the constructor fails, the whole type is unusable for the rest of the applicaiton.

I prefer to initialize variables as soon as possible, since it avoids (some) null errors.

Edit: Obviously in this simplified example there is no difference, however in the general case I believe it is good practice to initialize class variables when they are declared, if possible. This makes it impossible to refer to the variable before it it initialized, which eliminates some errors which would be possible when you initialize fields in the constructor.

As you get more class variables and the initialization sequence in the constructor gets more complex, it gets easier to introduce bugs where one initialization depends on another initialization which haven't happend yet.

Your comment doesn't really apply here. The variables are being initialized at the same time regardless of which method is used.
–
HermsOct 29 '08 at 18:40

The commenter's edited comment has a good point--if I have a field with an initializer, I KNOW it will be initialized. If I have a field in a class with 20 constructors, it's harder to make sure the variable is initialized before it is ever used. The Eric Lippert post makes this even more true.
–
Neil WhitakerOct 29 '08 at 23:16