views:

6782

answers:

5

Is it better to initialize class member variables on declaration

private List<Thing> _things = new List<Thing>();
private int _arb = 99;

or in the default constructor?

private List<Thing> _things;
private int _arb;

public TheClass()
{
  _things = new List<Thing>();
  _arb = 99;
}

Is it simply a matter of style or are there performance trade-offs, one way or the other?

A: 

For instance variables, it is largely a matter of style (I prefer using a constructor). For static variables, there is a performance benefit to initializing inline (not always possible, of course).

HTH, Kent

Kent Boogaart
A: 

It's really up to you.
I often initialize them inline, cause I don't like having a constructor when I don't really need one (I like small classes !).

Nico
+8  A: 

In terms of performance, there is no real difference; field initializers are implemented as constructor logic. The only difference is that field initializers happen before any "base"/"this" constructor.

The constructor approach can be used with auto-implemented properties (field initializers cannot) - i.e.

[DefaultValue("")]
public string Foo {get;set;}
public Bar() { // ctor
  Foo = "";
}

Other than that, I tend to prefer the field initializer syntax; I find it keeps things localized - i.e.

private readonly List<SomeClass> items = new List<SomeClass>();
public List<SomeClass> Items {get {return items;}}

I don't have to go hunting up and down to find where it is assigned...

The obvious exception is where you need to perform complex logic or deal with constructor parameters - in which case constructor-based initialization is the way to go. Likewise, if you have multiple constructors, it would be preferable for the fields to always get set the same way - so you might have ctors like:

public Bar() : this("") {}
public Bar(string foo) {Foo = foo;}

edit: as a side comment, note that in the above, if there are other fields (not shown) with field initializers, then they are only directly initialized in the constructors that call base(...) - i.e. the public Bar(string foo) ctor. The other constructor does not run field initializers, since it knows they are done by the this(...) ctor.

Marc Gravell
+4  A: 

Actually, field initializers as you demonstrate is a convenient shorthand. The compiler actually copies the initialization code into the beginning of each instance constructor that you define for your type.

This has two implications: first, any field initialization code is duplicated in each constructor and, second, any code you include in your constructors to initialize fields to specific values will in fact re-assign the fields.

So performance-wise, and with regards to compiled code size, you're better off moving field initializers into constructors.

On the other hand, the performance impact and code 'bloat' will usually be negligable, and the field initializer syntax has the important benefit of lessening the risk that you might forget to initialize some field in one of your constructors.

Tor Haugen
The performance point only applies if you re-assign the values (i.e. it doesn't apply in the original code). Likewise, the "bloat" issue (which is minuscule) only applies to ctors that call base(...) - so you can side-step this with a private ctor (as posted) - only this ctor will init the fields.
Marc Gravell
A: 

Use either field initializers or create an Init() function. The problem with putting these things in your constructor is that if you ever need to add a 2nd constructor, you end up with copy/paste code (or you overlook it and end up with uninitialized variables).

I would either initialize where declared. Or have the constructor(s) call an Init() function.

GeekyMonkey
Note the use of : this() to chain constructors in Marc Gravell's post above. This is a much better practice than writing separate Init()-functions.
Tor Haugen