Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C#
There are two ways to initialize members in a C# class, via constructor:
class MyClass{
  private int Member;
  public MyClass()
  {
    Member = 0;
  }
}
or through member initialization:
class MyClass
{
  private int Member = 0;
}
My question: Are there problems / benefits of one approach vs. another?
 
From what I can see, it's a wash if you only have a default constructor. If you have multiple constructors, member initialization is preferable for those members that are set to the same value by all constructors.
Posted 15-Jan-09 5:38am
Edited 2-Jan-13 8:37am
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Gary,

If the class calls Finalize, then using member initialization is certainly the right way to go. The reason being, if there is an error in the constructor, and Finalize is called, then the state of the fields could come into play. Using member initialization in this case means that you know your fields are valid, so you won't have issues if finalize is called following failed object construction.

D.



Last modified: 12mins after originally posted --


  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

I don't think it really matters, especially in the case of setting variables to their default values (which is recommended to not do). If you have multiple constructors, you can set the initial values in your simplest constructor and then use constructor chaining. In your first example, you actually end up with 3 additional lines of IL in the constructor to handle loading the arguement on to the evaluation stack (which it already does), then loading the 0 as an integer on to the evaluation stack, and then replacing the value stored in the "Member" field with the new value.

  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

There's a subtle difference if you call virtual methods from your constructor, which is generally not advisable. When generating IL code for the constructor, the C# compiler puts code for all field initializers before code for the constructor's body This means that overridden will see initialized values for field initialized members, but will see default values for others.


class Base
{
   protected int x = 42;
   protected int y;

   public Base()
   {
      SomeVirtualMethod();
      y = 42;
   }

   protected virtual void SomeVirtualMethod() {}
}

class Derived : Base
{
   protected override void SomeVirtualMethod()
   {
      Console.WriteLine(x);
      Console.WriteLine(y);
   }
}



prints 42 and 0.

  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 7

It will also affect debugging when you step into code so I often prefer to do initialization in the constructor as it make debugging somewhat easier.
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 5

Gary, in your case, this will do:
class MyClass
{
  private int Member;
}
Class level members are always initialized to default values. Strings are empty, numbers are 0, and bools are false.

  Permalink  
Comments
David St. Hilaire at 2-Jan-13 16:28pm
   
I believe strings are initialized to null.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

FXCop will trigger an "issue" if you do the 2nd thing, but FXCop is, after all, just a style guide and most of what it chokes/pukes on can safely be ignored. I tend to use method #2 in your examples.

  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 325
1 DamithSL 140
2 Zoltán Zörgő 120
3 Afzaal Ahmad Zeeshan 105
4 ProgramFOX 105
0 OriginalGriff 160
1 ProgramFOX 105
2 Sergey Alexandrovich Kryukov 60
3 Mehdi Gholam 50
4 DamithSL 50


Advertise | Privacy | Mobile
Web01 | 2.8.150224.1 | Last Updated 23 Sep 2014
Copyright © CodeProject, 1999-2015
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100