2009-08-21 60 views
7

我只是来了解虚拟和Override的是使用了(我找不到这么长时间使用)的后面。 现在我在工厂模式中使用它们。所以我的问题是Virtual和Override在幕后做了什么?我愿意接受IL和机器代码。什么是虚拟和覆盖做现场

回答

15

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

当编译器看到的代替方法附接到类虚拟方法声明,它把它添加到所谓的vtable(虚拟方法表),选择那些类,其保持指针的功能。

现在,由于vtable是类的一部分,它的子类继承,因此虚拟方法也被继承。现在出现覆盖位。当编译器看到的覆盖在方法声明中,它看起来了vtable,发现要覆盖的方法,因此它指向新的定义改变了函数指针。

因此,你既是从父类的方法继承和更改子类及其定义的能力。

欲了解更多信息,请参阅Virtual Method Table维基百科的文章。

+1

很好的解释! – Chris 2009-08-21 06:28:00

+0

难道是vtable中的方法实际上被链接而不是被覆盖?我的目标是从覆盖方法,我们可以调用基地重写的方法。 – 2009-08-21 06:44:35

+0

我认为链是隐含的继承。当你调用基本方法时,实际上是查找由基类定义的虚方法的定义并调用该方法。实际上,您可以查找基类的vtable并使用它。这就是为什么你需要使用base调用它,以便编译器知道去哪里看。 – paracycle 2009-08-21 07:01:01

4

你不需要去到IL - virtualoverride包括被称为polymorphism知名的面向对象的概念。有效地,当多晶型方法或属性被访问,该方法/属性实际上适用在运行时仅确定。为找到正确的方法,基于所述运行时类型的查找表 - 引擎盖下的,基本上,正确的方法(在一个属性的情况下,这是一个方法为好)是通过访问一个虚拟方法表确定。

4

如果你有兴趣的IL,使用程序Ildasm.exe来看看编译的程序(DLL或EXE)。你会发现你标记为“虚拟”的方法在IL中被简单地标记为“虚拟”。

神奇发生在运行时。 CLR构建一个“方法调度表”(或“虚拟方法表”),它用来在内存中定位你的类的方法。为了允许多态性,根据运行时类型,相同的方法名意味着不同的事情,虚拟方法需要一些额外的查找。 (有人可能会说,他们被称为“虚拟”的方法,恰恰是因为他们是“由凭借”选择的,他们正在以—但看到@帕维尔的意见是什么。)Joe Duffy这样说:

虚方法电话是非常 像一个普通的电话,除了它 必须基于“这个”对象中查找调用的目标在 运行。

这些都是基础知识。如果你真的想更进一步,Don Box是很好的阅读。

+0

这是一个有趣的'虚拟'的词源,但我会很好奇,如果这是一个回顾性的解释(就像VB的'昏暗'被解释为'声明在内存中'有些日子 - 最初它来自'DIMension',并只用于数组),或真实的东西;如果是后者,你有没有参考?我知道,在这个精确的意义上,“虚拟”首先出现在第一个OO语言Simula-67中。但我不记得看到关于该语言参考中的关键字的解释... – 2009-08-21 07:32:16

+0

好吧,所以我要出去在那边......但我觉得很安全。内存声明是我的新内容 - 我只知道它是旧的数组维度关键字。无论如何,很高兴听到一个同胞linguaphile。 – harpo 2009-08-21 07:46:50

+0

我相信我找到了。 “虚拟”是“虚拟量”的缩写。他们之所以这么称呼是因为他们最初设想了主要用于属性的机制。请参阅http://books.google.com/books?id=6f-8ZhMO3ScC&lpg=PA104&ots=EDFoUJSTBK&dq=simula%20%22virtual%20quantity%22&pg=PA105#v=onepage&q=virtual&f=false – 2009-08-21 19:46:48