C# member variable initialization; best practice?

C#ConstructorDeclaration

C# Problem Overview


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?

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

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).

Solution 5 - C#

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.

Solution 6 - C#

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 !).

Solution 7 - C#

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(){}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionSteve CraneView Question on Stackoverflow
Solution 1 - C#Marc GravellView Answer on Stackoverflow
Solution 2 - C#Tor HaugenView Answer on Stackoverflow
Solution 3 - C#supercatView Answer on Stackoverflow
Solution 4 - C#Kent BoogaartView Answer on Stackoverflow
Solution 5 - C#GeekyMonkeyView Answer on Stackoverflow
Solution 6 - C#NicoView Answer on Stackoverflow
Solution 7 - C#QubitsView Answer on Stackoverflow