Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# member variable initialization; best practice?

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?

like image 839
Steve Crane Avatar asked Nov 18 '08 08:11

Steve Crane


2 Answers

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.

like image 92
Marc Gravell Avatar answered Sep 28 '22 22:09

Marc Gravell


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.

like image 38
Tor Haugen Avatar answered Sep 28 '22 22:09

Tor Haugen