4

Possible Duplicate:
C# member variable initialization; best practice?

Which is the right way to initialize class variables. What is the difference between [1] and [2].

//[1]
public class Person
{
   private int mPersonID = 0; 
   private string mPersonName = "";
}

OR

//[2]
public class Person
{
     private int mPersonID = 0; 
     private string mPersonName = "";

     public Person()
     {
         InitializePerson();
     }

     private void InitializePerson()
     {
          mPersonID = 0;
          mPersonName = "";
     }
}
Community
  • 1
  • 1
softwarematter
  • 28,015
  • 64
  • 169
  • 263
  • There is similar question here: http://stackoverflow.com/questions/298183/c-member-variable-initialization-best-practice – RandomWebGuy Jun 09 '11 at 03:21

3 Answers3

6

Instance variables that are assigned a default value as part of their declaration will get this value assigned right before the constructor is run, from the outside there is no perceptible difference in behavior between 1) and 2), it's mostly a matter of style.

You also introduce an additional InitializePerson() method in your approach 2) - this can be beneficial if you have multiple constructors that then all can use the same common initialization method (which keeps the code DRY).

Edit in response to comment, see MSDN:

Fields are initialized immediately before the constructor for the object instance is called. If the constructor assigns the value of a field, it will overwrite any value given during field declaration.

BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • How is it possible to have fields assigned `right before the constructor`? – Alex Aza Jun 09 '11 at 03:25
  • @Alex: that's how it works, also you check out http://msdn.microsoft.com/en-us/library/ms173118%28v=vs.80%29.aspx for a reference – BrokenGlass Jun 09 '11 at 03:27
  • I wish the person who wrote this explained how code can be called `just before the constructor`. Take a look at my answer, the code is definitely inside of the constructor. – Alex Aza Jun 09 '11 at 03:31
  • 1
    true that, can't argue with the IL. I guess semantically in this context there is not much difference between the field initializer code being put at the beginning of the constructor or saying they are executed right before the constructor call. There are limitations in field initializers though (i.e can't access other instance fields) that make them different from "other" constructor code. – BrokenGlass Jun 09 '11 at 03:37
  • 1
    You'd see a difference when there's a base class. The derived members will be initialized, then the base constructor will be called, then the derived constructor will complete. – Anthony Pegram Jun 09 '11 at 03:42
  • It should be noted that in VB, the fields are initialized after the constructor. http://stackoverflow.com/questions/4602468/can-vb-net-be-forced-to-initialize-instance-variables-before-invoking-the-base-t – Chris Zeh Nov 12 '12 at 17:51
2

In both cases it will generate IL that will look almost the same. Saying 'almost', because you introduced extra method in the second approach. If you just put it to constructor, than it would be THE same IL code.

So it is better to use approach #1 as it is less code.

Also you don't need to assign default values (0 for int, null for reference types).

These two examples generate identical IL:

public class Test
{
    private string test1 = "";
}

public class Test
{
    private string test1;

    public public Test()
    {
        test1 = "";
    }
}

IL:

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
    .maxstack 8
    L_0000: ldarg.0 
    L_0001: ldstr ""
    L_0006: stfld string ConsoleApplication1.Test::test1
    L_000b: ldarg.0 
    L_000c: call instance void [mscorlib]System.Object::.ctor()
    L_0011: nop 
    L_0012: ret 
}
Alex Aza
  • 76,499
  • 26
  • 155
  • 134
  • So I need to assign string to "", right? – softwarematter Jun 09 '11 at 03:18
  • yes, if you want it to be equal "", which is not the same as null – Andrew Savinykh Jun 09 '11 at 03:20
  • Is there some specific reason you'd want to default a string to an empty string instead of null? If not, then no, you don't have to. – Khepri Jun 09 '11 at 03:21
  • You don't "need" to assign "" to string, as that is the default value for a string type, but if you are going to it is better to use string.Empty than quotes (almost imperceptively so, but still) – Cos Callis Jun 09 '11 at 03:21
  • @Cos, you are incorrect. `null` is the default for a string as well as other reference types. An empty string must be set explicitly. – Anthony Pegram Jun 09 '11 at 03:24
  • @andromeda - If you want to have `""`, you need to specifically assign it, otherwise it will be `null`. Side note: use `string.Empty` instead of `""`, if null doesn't work for you of course. – Alex Aza Jun 09 '11 at 03:27
  • @Anthony, as I read the question there is no imperative to initialize the string to any value. OP asks "what the difference is" to begin with and then follows up with `So I _need_ to assign string to "", right? `. My response is there is no "NEED" to do so as it is operationally the same, but that if he chooses to initialize, it is better to use a system constant (string.Empty) over a pair of quotes. – Cos Callis Jun 09 '11 at 03:31
0

In the 2nd case, if you try referencing mPersonName in the constructor before you assign it in InitializePerson, you'll get a null reference exception since String is NULL by default. int default value is 0 so there is no issue there. In the first case, you don't have to worry about where you use them in your constructor since you assign values on declaration at the class level. Otherwise, there is no difference.

alexD
  • 2,368
  • 2
  • 32
  • 43