我刚刚了解Virtual和Override用于(我找不到这么长时间使用)。 现在我在Factory Patterns中使用它们。所以我的问题是Virtual和Override在幕后做了什么?我愿意进入IL和机器代码。
答案 0 :(得分:15)
我无法向你提供有关如何在IL中完成的任何见解,但基本理论很简单。
当编译器看到虚拟方法声明时,不会将该方法附加到类中,而是将其添加到所谓的 vtable
(a该类的虚方法表,其中包含指向函数的指针。
现在,由于 vtable
是类的一部分,因此它由子类继承,因此虚拟方法也是继承的。现在是覆盖位。当编译器在方法声明中看到覆盖时,它会查找 vtable
,找到要覆盖的方法并更改函数指针,使其指向新的定义。
因此,您既可以从父类继承方法,也可以在子类中更改它们的定义。
有关详情,请参阅Virtual Method Table上的维基百科文章。
答案 1 :(得分:4)
您不需要进入IL - virtual
和override
包含一个众所周知的面向对象概念,称为polymorphism。实际上,当访问多态方法或属性时,实际应用的方法/属性仅在运行时确定。在引擎盖下,基本上,正确的方法(在属性的情况下,它也是一种方法)是通过访问虚拟方法表 - 用于查找正确方法的查找表来确定的,基于运行时类型。
答案 2 :(得分:4)
如果您对IL感兴趣,请使用ildasm.exe查看已编译的程序(DLL或EXE)。您将看到标记为“虚拟”的方法在IL中仅标记为“虚拟”。
魔术发生在运行时。 CLR构建了一个“方法调度表”(或“虚方法表”),用于在内存中定位类的方法。为了允许多态性,其中相同的方法名称根据运行时类型意味着不同的东西,虚拟方法需要一些额外的查找。 (人们可以说它们被称为“虚拟”方法,正是因为它们是“凭借”它们的操作而选择的 - 但请参阅@ Pavel的评论。)Joe Duffy这样说:
虚拟方法调用非常多 就像一个普通的电话,除了它 必须查看电话的目标 运行时基于'this'对象。
这些是基础知识。如果你真的想进一步了解,Don Box是一个很好的阅读。