?
Solved

Advanced Programmers Only: Initialize variables at declartion vs in constructor

Posted on 2004-12-01
8
Medium Priority
?
177 Views
Last Modified: 2010-04-15
This is more of a theoretical / best practice / most  efficeint method type of question...

The following two pieces of code have the same effect:

public class MyClass
{
    int test = 1;
}

public class MyClass
{
   int test;
   MyClass() {test = 1;}
}


Is it better/more effiecient/etc to assign defaut values when you declare a variable or to assign the values in the default constructor?
Is it just preference?

One advantage to initializing at the time of declaration is that if you have multiple values and multiple constructors the constructors only have to deal with the few values.

i.e.

public class MyClass
{
   int test1 = 1;
   int test2 = 2;
   int test3 = 3;
   int test4 = 4;
   int test5 = 5;
   int test6 = 6;

   MyClass(int x)
  { test1 = x;} // test2 through test6 keep default values

  MyClass(int x, int y)
    {  test1 = x; test2 = y; } // test3 through test6 keep default values
}

versus

public class MyClass
{
   int test1;
   int test2;
   int test3;
   int test4;
   int test5;
   int test6;

   MyClass(int x)
   {
       test1 = x;
       test2 = 2;
       test3 = 3;
       test4 = 4;
       test5 = 5;
       test6 = 6;
   }

   MyClass(int x, int y)
   {
       test1 = x;
       test2 = y;
       test3 = 3;
       test4 = 4;
       test5 = 5;
       test6 = 6;
   }
}

However if you can chain the constructors like so then does that advantage get counteracted?

public class MyClass
{
   int test1;
   int test2;
   int test3;
   int test4;
   int test5;
   int test6;

   MyClass()
   {
       test1 = 1;
       test2 = 2;
       test3 = 3;
       test4 = 4;
       test5 = 5;
       test6 = 6;
    }

   MyClass(int x) : this()
   {
       test1 = x;
   }

   MyClass(int x, int y) : this()
   {
       test1 = x;
       test2 = y;
   }
}


Comments appreciated....
0
Comment
Question by:mrichmon
8 Comments
 
LVL 48

Accepted Solution

by:
AlexFM earned 1400 total points
ID: 12719218
I created application with two classes:

    public class MyClass1
    {
        int test = 1;
        MyClass1() {  }
    }

    public class MyClass2
    {
        int test;
        MyClass2() { test = 1; }
    }

built it in the Release configuration and opened in ILDASM. This is how their constructors look in MSIL.
Class1:

.method private hidebysig specialname rtspecialname
        instance void  .ctor() cil managed
{
  // Code size       14 (0xe)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.1
  IL_0002:  stfld      int32 Test.MyClass1::test
  IL_0007:  ldarg.0
  IL_0008:  call       instance void [mscorlib]System.Object::.ctor()
  IL_000d:  ret
} // end of method MyClass1::.ctor

Class2:

.method private hidebysig specialname rtspecialname
        instance void  .ctor() cil managed
{
  // Code size       14 (0xe)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
  IL_0006:  ldarg.0
  IL_0007:  ldc.i4.1
  IL_0008:  stfld      int32 Test.MyClass2::test
  IL_000d:  ret
} // end of method MyClass2::.ctor

Code is the same, but different lines order. Two versions performance is the same.
0
 
LVL 35

Author Comment

by:mrichmon
ID: 12719497
I knew about the order difference.

I read "C# takes any initializers and executes them in the order declared before executing the constructor"  But since they are called one right after the other I am not sure that the order difference even matters....

I would expect that for a small example the performance would be the same, but what if you have a lot of variables?  Would it still not affect performance?


Which way do you prefer and why?

Thanks for the comments!
0
 
LVL 48

Assisted Solution

by:AlexFM
AlexFM earned 1400 total points
ID: 12719623
All performance issues should be learned by reading MSIL code in the Release configuration. Exactly like in unmanaged C++, where we need to read Assembly code generated by compiler. Without looking at actual code all our assumptions are only theory.
I don't see difference between initializing of one or number of variables. Instead of one ldc lune you will get number of lines. In the first case, before calling of System.Object::.ctor(). In the second case, after this call.
If you are interesting in such issues, read about MSIL and ILDASM tool and about just-in-time compilation.

I don't have any preference in variables initialization.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 35

Author Comment

by:mrichmon
ID: 12721407
I am not totally sure how to go about finding the MSIL code that you showed, although I am able to read and understand it ;o)

So your point makes sense.

But here's a twist - waht if they were no longer simple types but user classes themselves....

Thanks for your input.
0
 
LVL 22

Assisted Solution

by:_TAD_
_TAD_ earned 200 total points
ID: 12721640


I haven't run any tests yet, but instead of just one or two variables, assume you have 1,000 variables.  Not just primatives either, but actual objects.

Is there any difference in memory usage?  Obviously there won't be from within the class itself, but what about a calling class?  When do those variables begin to take up space in memory?

For example:

Class Vars1
{
    // variable init here
}

Class Vars2
{
   Vars2(){//variables init here}
}

Class CallingClass
{
    public Vars1 myVar1;
    public Vars2 myVar2;

    public void Button1Press(){myVar1 = new Vars1();}
    public void Button2Press(){myVar2 = new Vars2();}
}



If no buttons are ever pushed, would you be better off (memory-wise) if you declared your variables in a particular method over another?


I *think* that the space in memory is not actually reserved/used until the variable is initialized.
0
 
LVL 48

Assisted Solution

by:AlexFM
AlexFM earned 1400 total points
ID: 12723678
0
 
LVL 7

Assisted Solution

by:NipNFriar_Tuck
NipNFriar_Tuck earned 400 total points
ID: 12727208
One overriding reason that I recommend against intitializing variable outside of the constructor is errors on complex objects.  When I started with C# I thought that this was mainly a matter of preference.  However, while working on a large project that uses a number of 3rd party assemblies and inhouse assemblies I came accross an issue that was... interesting.  It seems that when you initialize a variable in the class name space (as opposed to a function/constructor) then there is an implied system try catch around the initialization.  What this means is that if the object being initialized errors out for any reason the control of the application jumps directly to the system and it can not be caught, at least this was my experience, even if the initialization of the class is in a try catch...  i.e. Class1 has a member var of Class2... Class1 initializes Class2 in an Init() function in a try catch... Class2 has a member var of Class3 but does private Class3 c3 = new Class3;  When Class3 fails to initialize Class2 fails out to the System implied try catch instead of to the try catch where class2 was being initialized.  Because of this experience I recommend that an Init() function be written that initializes all variables then you can have as many constructors that you want that dummy the values that they do not have passed in...

Something to think about...
0
 
LVL 35

Author Comment

by:mrichmon
ID: 12727285
good thoughts - thanks for the comments!
0

Featured Post

Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

One of a set of tools we're offering as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

We all know that functional code is the leg that any good program stands on when it comes right down to it, however, if your program lacks a good user interface your product may not have the appeal needed to keep your customers happy. This issue can…
It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Loops Section Overview
Look below the covers at a subform control , and the form that is inside it. Explore properties and see how easy it is to aggregate, get statistics, and synchronize results for your data. A Microsoft Access subform is used to show relevant calcul…

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question