Friday, September 21, 2007

Boxing Mystery in Overloaded and Overridden Method

Recently I have produced a code with strange behaviour in my real C# project. Look at this code:

class BaseMystery

{

  public virtual void Foo(int i) { }

}

 

class Mystery : BaseMystery

{

  private void Foo(object i)

  {

    Console.WriteLine("Finished.");

  }

 

  public new void Foo(int i)

  {

    Foo(i);

  }

}

 

static void Main(string[] args)

{

  Mystery mystery = new Mystery();     

  mystery.Foo(3);

}


It produces:

Process is terminated due to StackOverflowException.


There is nothing strange. The method Mystery.Foo(int) is called repeatedly. Then I replaced hidding method Mystery.Foo(int) by overriding method:

class BaseMystery

{

  public virtual void Foo(int i) { }

}

 

class Mystery : BaseMystery

{

  private void Foo(object i)

  {

    Console.WriteLine("Finished.");

  }

 

  public override void Foo(int i)

  {

    Foo(i);

  }

}

 

static void Main(string[] args)

{

  Mystery mystery = new Mystery();     

  mystery.Foo(3);

}


And the output is:

Finished.


Hah! What is the matter? Let us go to explore IL code of method Mystery.Foo(int):

public new void Foo(int)


.method public hidebysig instance void Foo(int32 i) cil managed

{

  .maxstack 8

  L_0000: nop

  L_0001: ldarg.0

  L_0002: ldarg.1

  L_0003: call instance void BoxingMystery.Program/Mystery::Foo(int32)

  L_0008: nop

  L_0009: ret

}


and

public override void Foo(int)


.method public hidebysig virtual instance void Foo(int32 i) cil managed

{

  .maxstack 8

  L_0000: nop

  L_0001: ldarg.0

  L_0002: ldarg.1

  L_0003: box int32

  L_0008: call instance void BoxingMystery.Program/Mystery::Foo(object)

  L_000d: nop

  L_000e: ret

}


Argument i has been boxed. Why? I would expect that the IL body of method Mystery.Foo(int) will be the same in new and override declaration but it is different. It is very strange behaviour of compiler. What is your explanation?

Overridded method in my real project was the right one. In addition, I renamed the methods, because my colleagues could be confused like me.

kick it on DotNetKicks.com

1 comment:

Anonymous said...

What a great web log. I spend hours on the net reading blogs, about tons of various subjects. I have to first of all give praise to whoever created your theme and second of all to you for writing what i can only describe as an fabulous article. I honestly believe there is a skill to writing articles that only very few posses and honestly you got it. The combining of demonstrative and upper-class content is by all odds super rare with the astronomic amount of blogs on the cyberspace.