gpt4 book ai didi

c# - 关于继承 C#

转载 作者:太空狗 更新时间:2023-10-29 23:23:22 25 4
gpt4 key购买 nike

我想了解继承在 C# 中的工作原理。我写了下面的代码:

class Program
{
static void Main(string[] args)
{
Animal animal = new Dog();
animal.OverRideMe();
//animal.NewMethod();
Dog dog = (Dog)animal;
dog.OverRideMe();
dog.NewMethod();
Console.Read();
}
}
public abstract class Animal
{
public Animal()
{
Console.WriteLine("Base Constructor");
}
public virtual void OverRideMe()
{
Console.WriteLine("In Base Class's OverRideMe");
Console.Read();
}
}
public class Dog : Animal
{
public Dog()
{
Console.WriteLine("Derived Constructor");
}
public override void OverRideMe()
{
Console.WriteLine("In Derived Class's OverRideMe");
Console.Read();
}
public void NewMethod()
{
Console.WriteLine("In Derived Class's NewMethod");
Console.Read();
}
}

Main() 的 CIL(通用中间语言)代码如下所示:

.method private hidebysig static 
void Main (
string[] args
) cil managed
{
// Method begins at RVA 0x2050
// Code size 42 (0x2a)
.maxstack 1
.entrypoint
.locals init (
[0] class ConsoleApplication1.Animal animal,
[1] class ConsoleApplication1.Dog dog
)

IL_0000: nop
IL_0001: newobj instance void ConsoleApplication1.Dog::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: callvirt instance void ConsoleApplication1.Animal::OverRideMe()
IL_000d: nop
IL_000e: ldloc.0
IL_000f: castclass ConsoleApplication1.Dog
IL_0014: stloc.1
IL_0015: ldloc.1
IL_0016: callvirt instance void ConsoleApplication1.Animal::OverRideMe()
IL_001b: nop
IL_001c: ldloc.1
IL_001d: callvirt instance void ConsoleApplication1.Dog::NewMethod()
IL_0022: nop
IL_0023: call int32 [mscorlib]System.Console::Read()
IL_0028: pop
IL_0029: ret
} // end of method Program::Main

CIL 中令我困扰的行是:

IL_000f: castclass ConsoleApplication1.Dog
IL_0014: stloc.1
IL_0015: ldloc.1
IL_0016: callvirt instance void ConsoleApplication1.Animal::OverRideMe()
IL_001b: nop
IL_001c: ldloc.1
IL_001d: callvirt instance void ConsoleApplication1.Dog::NewMethod()

animalDogcastclass 之后,代码执行 dog.OverRideMe();。这被翻译成 CIL 为

IL_0016: callvirt instance void ConsoleApplication1.Animal::OverRideMe()

我已经将 animal 对象转换为 Dog 类型。为什么dog.OverRideMe();在CIL中要翻译成上面的语句?上面代码的输出是:

enter image description here

此输出与基类 Animal 无关,但 CIL 仍会调用它。

最佳答案

您正在调用一个虚拟方法。虚方法调用由对象的运行时 类型决定。您可以随心所欲地称它为 Dog,但编译器仍会发出指令以确定在运行时 调用的适当方法。从dog编译时 类型开始,它沿着继承链向上走,直到找到1 的“顶层”定义OverRideMe 并为此发出一个虚拟方法调用。在这种情况下,OverRideMe 定义的继承链中的最高位置是在Animal 中;因此,它为 Animal.OverRideMe 发出一个虚拟方法调用。

这是一个 previous answer这可能会帮助您更好地了解正在发生的事情。

1:定义方法的继承链中的最高位置。 一些这里必须小心理解方法隐藏的方式以及什么不会影响它。

关于c# - 关于继承 C#,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18190152/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com