Diciamo che abbiamo seguente codice di esempio in C#:Perché compilatore C# metodo di produzione di chiamata per chiamare il metodo BaseClass in IL
class BaseClass
{
public virtual void HelloWorld()
{
Console.WriteLine("Hello Tarik");
}
}
class DerivedClass : BaseClass
{
public override void HelloWorld()
{
base.HelloWorld();
}
}
class Program
{
static void Main(string[] args)
{
DerivedClass derived = new DerivedClass();
derived.HelloWorld();
}
}
Quando ho ildasmed il seguente codice:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 15 (0xf)
.maxstack 1
.locals init ([0] class EnumReflection.DerivedClass derived)
IL_0000: nop
IL_0001: newobj instance void EnumReflection.DerivedClass::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: callvirt instance void EnumReflection.BaseClass::HelloWorld()
IL_000d: nop
IL_000e: ret
} // end of method Program::Main
Tuttavia, csc .exe convertito derived.HelloWorld();
->callvirt instance void EnumReflection.BaseClass::HelloWorld()
. Perché? Non ho citato BaseClass ovunque nel metodo Main
.
E anche se sta chiamando BaseClass::HelloWorld()
quindi mi aspetterei call
invece di callvirt
dal momento che sembra chiamata diretta a BaseClass::HelloWorld()
metodo.
Lanciare questa idea, ma non lo so: potrebbe essere un'ottimizzazione del compilatore in quanto il metodo si chiama semplicemente l'implementazione di base. – payo
@payo no; anche se l'override avesse una logica unica, il callvirt sarebbe lo stesso. – phoog
@phoog questo non è lo stesso per tutte le lingue - posso vedere come questo è il caso per C# tho – payo