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?
One major limitation with field initializers is that there's no way to wrap them in a try-finally block. If an exception is thrown in a field initializer, any resources that were allocated in previous initializers will be abandoned; there's no way to prevent it. Other errors in construction can be dealt with, if awkwardly, by having a protected base constructor accept an IDisposable by reference, and pointing it at itself as its very first operation. One can then avoid calling the constructor except through factory methods which in case of exception will call Dispose on the partially-created object. This protection will allow for cleanup of IDisposables created in derived-class initializers if the main-class constructor fails after "smuggling out" a reference to the new object. Unfortunately, there's no way to provide such protection if a field initializer fails.
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.
Other than that, I tend to prefer the field initializer syntax; I find it keeps things localized - i.e.
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:
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. thepublic Bar(string foo)
ctor. The other constructor does not run field initializers, since it knows they are done by thethis(...)
ctor.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).
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 !).
On added point to the above - You always have a constructor when implementing classes that have an implementation. If you do not declare one then the default instructor is inferred by the compiler [public Foo(){}]; a constructor that takes no arguments.
Often times I like to offer both approaches. Allow constructors for those that wish to use them and allow the Field Initializers for situations where you wish to use a simplified or default implementation of your class / type. This adds flexibility to your code. Keep in mind that anyone can use the default field initializer if they choose ... be sure to declare it manually if you offer more than one constructor - public Foo(){}
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.