Advanced Programmers Only: Initialize variables at declartion vs in constructor

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....
LVL 35
mrichmonAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

AlexFMCommented:
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

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
mrichmonAuthor Commented:
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
AlexFMCommented:
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
Cloud Class® Course: CompTIA Healthcare IT Tech

This course will help prep you to earn the CompTIA Healthcare IT Technician certification showing that you have the knowledge and skills needed to succeed in installing, managing, and troubleshooting IT systems in medical and clinical settings.

mrichmonAuthor Commented:
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
_TAD_Commented:


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
NipNFriar_TuckCommented:
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
mrichmonAuthor Commented:
good thoughts - thanks for the comments!
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C#

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.