Best Practices and Member Initialization in C#

Today I thought I would present two slightly different approaches to class member initialization and see what people were doing out there. When you define a class you have the option to initialize member variables in the declaration or in the constructor. Here's our class creating a new ArrayList at declaration time:

public class MyClass

{

    private ArrayList myList = new ArrayList();

 

    public MyClass()

    {

    }

}

 
So you create a new instance of MyClass and the array list it created for you. The second example is to initialize it to null (a C++ type approach) and then "create" it in the constructor:
 

public class MyClass

{

    private ArrayList myList = new ArrayList();

 

    public MyClass()

    {

        myList = new ArrayList();

    }

}

 
Pretty much the same effect isn't it. There is one danger in initializing the ArrayList at declaration time though. Sometimes a developer might come along and create another constructor and re-initialize or create the ArrayList again:
 

public class MyClass

{

    private ArrayList myList = null;

 

    public MyClass()

    {

        myList = new ArrayList();

    }

}

No big deal in C# as it'll just add a few more operations at the IL code. No harm no foul. However if your field wasn't an ArrayList but another more complex class (that maybe incorporated other classes) it might not produce the wanted effect (especially if you read a config file or something to initialize values like in a data class to read the connection string).

Steve Eichert blogged about this a couple of years ago and asked the question as well. There didn't seem to be any hard and fast rule but there were a couple of interesting observations about it. James Curran mentioned that he prefers to initialze all data members at declaration because it parallels the initialization of local variables. That makes sense so why not? According to Sigurdur Gunnarsson, the other really interesting thing I didn't know (although I can't find it documented anywhere) is that initialization of some members (like say "string myString = string.Empty;" the compile will move the initialization into the constructor so he does his creation in the constructor to control order.

Is there a right way or wrong way here or is it a "it depends" answer? Do you have any standards you use around doing this like "all member variables will be initialized in the constructor" (at least for consistency). The Constructor Usage Guidelines in the .NET Framework General Reference doesn't seem to suggest one or the other (although the simple example they have initializes strings in the declaration).

PS anyone have a nice way of copy/paste code into .Text without it looking like it's been through the washing machine?

PPS thanks to Darrell Norton for the tip on the CopySourceAsHtml addin that I've updated the blog with. Works great!

3 Comments

  • IMHO the answer is "it depends" for instance members.



    It is worth noting that for *static* members, FxCop recommends initializing at declaration rather than in a static constructor. This seems to be a "performance" guideline, which seems slightly dubious to me as the code is only ever executed once in the lifetime of an Application Domain.

  • Example snippet 2 and 3 should be switched...

  • Good question , I also dont know what should be the standard and
    I just come across an example where I had to use field initialization in the declaration.

    I think field initialisation in the declaration is good in theory: You know it will happen first.. see comment above. E.g. if base classes are involved, and member initialisation is depending on other members . This way everyone can see that thei get intialised first. Also make it clear to everyone that they are constructed first.

    However by putting member initialisation in the constructor the class definition is cleaner to look at . All the members are in a neat and orderly list without any of their own constructors/ initialisation making it untidy. And I think this should be the default.



    Also you pasted the example code that goes into the second
    code box into the third code box adn vica verca.

Comments have been disabled for this content.