phép nói rằng chúng tôi đã theo mẫu mã trong C#:Tại sao biên dịch C# gọi phương thức sản để gọi phương thức BaseClass trong 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();
}
}
Khi tôi ildasmed đoạn mã sau:
.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
Tuy nhiên, csc .exe đã chuyển đổi derived.HelloWorld();
->callvirt instance void EnumReflection.BaseClass::HelloWorld()
. Tại sao vậy? Tôi đã không đề cập đến BaseClass ở bất cứ đâu trong phương thức Main
.
Và cũng có thể nếu nó đang gọi BaseClass::HelloWorld()
thì tôi mong đợi call
thay vì callvirt
vì có vẻ như gọi trực tiếp đến phương thức BaseClass::HelloWorld()
.
Chỉ cần ném ý tưởng này ra khỏi đó, nhưng tôi không biết - đây có thể là tối ưu hóa trình biên dịch vì phương pháp của bạn chỉ đơn giản là gọi triển khai cơ sở. – payo
@payo no; ngay cả khi ghi đè có một số logic duy nhất, callvirt sẽ giống nhau. – phoog
@phoog điều này không giống nhau đối với tất cả các ngôn ngữ - tôi có thể thấy trường hợp này như thế nào đối với C# tho – payo