Re: constructors/default values

"Bart De Smet [MVP]" <[email protected]> Tue, 2 Jan 2007 18:13:12 +0100
Newsgroups gmane.comp.windows.devel.dotnet.cx
Message-ID <015801c72e91$49936300$dcba2900$@net>
Hi folks,

As usual the difference is very subtle but rather important nevertheless.
Consider the following code fragment:

using System;

class Foo
{
   public Foo()
   {
      Console.WriteLine(this.ToString());
   }
}

class Bar1 : Foo
{
   private int i;

   public Bar1()
   {
      i = 123;
   }

   public override string ToString()
   {
      return i.ToString();
   }
}

class Bar2 : Foo
{
   private int i = 123;

   public Bar2()
   {
   }

   public override string ToString()
   {
      return i.ToString();
   }
}

class Program
{
   static void Main()
   {
      new Bar1();
      new Bar2();
   }
}

The first line of code, new Bar1(), will call Bar1's constructor, which on
its turn calls the base class' constructor (i.e. Foo::ctor), which on its
turn calls the virtual ToString method, resulting in a call to
Bar1::ToString. The result is 0. Reason: the base constructor is called
before the i = 123 statement is executed. IL (base ctor call on line
IL_0001, _before_ manual field initialization):

.method public hidebysig specialname rtspecialname
        instance void  .ctor() cil managed
{
  // Code size       18 (0x12)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  call       instance void Foo::.ctor()
  IL_0006:  nop
  IL_0007:  nop
  IL_0008:  ldarg.0
  IL_0009:  ldc.i4.s   123
  IL_000b:  stfld      int32 Bar1::i
  IL_0010:  nop
  IL_0011:  ret
} // end of method Bar1::.ctor

The second line of code, new Bar2(), will call Bar2's constructor, which on
its turn calls the base class' constructor (i.e. Foo::ctor), which on its
turn calls the virtual ToString method, resulting in a call to
Bar2::ToString. The result is 123. Reason: the base constructor is called
after all field initialization is done. IL (base ctor call on line IL_0009,
_after_ field initialization):

.method public hidebysig specialname rtspecialname
        instance void  .ctor() cil managed
{
  // Code size       18 (0x12)
  .maxstack  8
  IL_0000:  ldarg.0
  IL_0001:  ldc.i4.s   123
  IL_0003:  stfld      int32 Bar2::i
  IL_0008:  ldarg.0
  IL_0009:  call       instance void Foo::.ctor()
  IL_000e:  nop
  IL_000f:  nop
  IL_0010:  nop
  IL_0011:  ret
} // end of method Bar2::.ctor

Quiz: predict the output of the following code fragment:

using System;

abstract class Foo
{
   public Foo()
   {
      this.Calc();
   }

   public abstract void Calc();
}

class Bar : Foo
{
   private int i;
   private int j = 321;
   private int sum;

   public Bar()
   {
      i = 123;
      Console.WriteLine(sum);
   }

   public override void Calc()
   {
      sum = i + j;
   }
}

class Program
{
   static void Main()
   {
      new Bar();
   }
}

Have fun,

-Bart

-----Original Message-----
From: Discussion relating to the specifics of the C# and Managed C++
languages [mailto:[email protected]] On Behalf Of Peter Osucha
Sent: dinsdag 2 januari 2007 16:12
To: [email protected]
Subject: [DOTNET-CX] constructors/default values

What is the difference (practically) in assigning a variable value in the
variable declaration line and in the constructor?

Peter





===================================
This list is hosted by DevelopMentor.  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com

===================================
This list is hosted by DevelopMentorĀ®  http://www.develop.com

View archives and manage your subscription(s) at http://discuss.develop.com