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:
Hah! What is the matter? Let us go to explore IL code of method
Mystery.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.