8

我刚开始了解 Virtual 和 Override 是用于(我找不到这么久的用途)。现在我在工厂模式中使用它们。所以我的问题是 Virtual 和 Override 在幕后做了什么?我愿意进入 IL 和机器代码的东西。

4

3 回答 3

17

我不能给你任何关于它是如何在 IL 中完成的见解,但基本理论很简单。

当编译器看到一个虚拟方法声明时,它不会将该方法附加到类,而是将其添加到该类的所谓vtable(虚拟方法表)中,该表包含指向函数的指针。

现在由于vtable它是类的一部分,它被它的子类继承,因此虚方法也被继承。现在是覆盖位。当编译器在方法声明中看到覆盖时,它会查找vtable,找到要覆盖的方法并更改函数指针以使其指向新定义。

因此,您既可以继承父类的方法,也可以在子类中更改它们的定义。

有关详细信息,请参阅有关虚拟方法表的 Wikipedia 文章。

于 2009-08-21T06:27:10.933 回答
4

您无需深入了解 IL -virtualoverride包含一个众所周知的面向对象概念,即多态性。实际上,当访问多态方法或属性时,实际应用的方法/属性仅在运行时确定。在引擎盖下,基本上,正确的方法(在属性的情况下,它也是一种方法)是通过访问虚拟方法表来确定的- 一个用于根据运行时类型查找正确方法的查找表。

于 2009-08-21T06:28:13.083 回答
4

如果您对 IL 感兴趣,请使用 ildasm.exe 查看已编译的程序(DLL 或 EXE)。您会看到标记为“虚拟”的方法在 IL 中只是简单地标记为“虚拟”。

魔法发生在运行时。CLR 构建一个“方法分派表”(或“虚拟方法表”),用于在内存中定位类的方法。为了允许多态性,其中相同的方法名称根据运行时类型表示不同的东西,虚拟方法需要一些额外的查找。(人们可以说它们被称为“虚拟”方法正是因为它们是“凭借”它们正在操作的内容而被选中的——但请参阅@Pavel 的评论。) 乔·达菲这样说:

虚方法调用与普通调用非常相似,不同之处在于它必须在运行时根据“this”对象查找调用的目标。

这些是基础。如果您真的想进一步了解这一点,Don Box 是很好的阅读材料。

于 2009-08-21T06:30:15.340 回答