我只是来了解虚拟和Override的是使用了(我找不到这么长时间使用)的后面。 现在我在工厂模式中使用它们。所以我的问题是Virtual和Override在幕后做了什么?我愿意接受IL和机器代码。什么是虚拟和覆盖做现场
回答
我不能给你任何见解,它是如何在IL完成,但基本的原理很简单。
当编译器看到的代替方法附接到类虚拟方法声明,它把它添加到所谓的vtable
(虚拟方法表),选择那些类,其保持指针的功能。
现在,由于vtable
是类的一部分,它的子类继承,因此虚拟方法也被继承。现在出现覆盖位。当编译器看到的覆盖在方法声明中,它看起来了vtable
,发现要覆盖的方法,因此它指向新的定义改变了函数指针。
因此,你既是从父类的方法继承和更改子类及其定义的能力。
欲了解更多信息,请参阅Virtual Method Table维基百科的文章。
你不需要去到IL - virtual
和override
包括被称为polymorphism知名的面向对象的概念。有效地,当多晶型方法或属性被访问,该方法/属性实际上适用在运行时仅确定。为找到正确的方法,基于所述运行时类型的查找表 - 引擎盖下的,基本上,正确的方法(在一个属性的情况下,这是一个方法为好)是通过访问一个虚拟方法表确定。
如果你有兴趣的IL,使用程序Ildasm.exe来看看编译的程序(DLL或EXE)。你会发现你标记为“虚拟”的方法在IL中被简单地标记为“虚拟”。
神奇发生在运行时。 CLR构建一个“方法调度表”(或“虚拟方法表”),它用来在内存中定位你的类的方法。为了允许多态性,根据运行时类型,相同的方法名意味着不同的事情,虚拟方法需要一些额外的查找。 (有人可能会说,他们被称为“虚拟”的方法,恰恰是因为他们是“由凭借”选择的,他们正在以—但看到@帕维尔的意见是什么。)Joe Duffy这样说:
虚方法电话是非常 像一个普通的电话,除了它 必须基于“这个”对象中查找调用的目标在 运行。
这些都是基础知识。如果你真的想更进一步,Don Box是很好的阅读。
这是一个有趣的'虚拟'的词源,但我会很好奇,如果这是一个回顾性的解释(就像VB的'昏暗'被解释为'声明在内存中'有些日子 - 最初它来自'DIMension',并只用于数组),或真实的东西;如果是后者,你有没有参考?我知道,在这个精确的意义上,“虚拟”首先出现在第一个OO语言Simula-67中。但我不记得看到关于该语言参考中的关键字的解释... – 2009-08-21 07:32:16
好吧,所以我要出去在那边......但我觉得很安全。内存声明是我的新内容 - 我只知道它是旧的数组维度关键字。无论如何,很高兴听到一个同胞linguaphile。 – harpo 2009-08-21 07:46:50
我相信我找到了。 “虚拟”是“虚拟量”的缩写。他们之所以这么称呼是因为他们最初设想了主要用于属性的机制。请参阅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
- 1. 覆盖非虚拟功能和虚拟功能有什么区别?
- 2. C#继承 - 为什么使用覆盖和虚拟?
- 3. 了解虚拟/覆盖
- 4. C#虚拟内部工作和覆盖
- 5. 覆盖和隐藏虚拟功能
- 6. 虚拟和覆盖是什么?不是C#没有它们做同样的事情吗?
- 7. 虚拟,覆盖,新和密封覆盖之间的区别
- 8. 猫鼬虚拟现场
- 9. 为什么我的虚拟方法没有被覆盖?
- 10. C# - 为什么虚拟函数不能覆盖抽象函数?
- 11. 演员派生虚拟覆盖基地纯虚拟成员
- 12. 什么是虚拟代理?
- 13. 什么是虚拟内存?
- 14. 什么是序列覆盖?
- 15. 什么是“覆盖条件”?
- 16. C#继承虚拟或覆盖
- 17. 虚拟方法覆盖在C++
- 18. C#虚拟&覆盖关键字
- 19. 虚拟方法未被覆盖?
- 20. 覆盖合格的虚拟方法
- 21. 覆盖C++中的非虚拟继承
- 22. Castle.ActiveRecord如何覆盖虚拟属性?
- 23. 通过覆盖Win32文件API来实现虚拟文件
- 24. C#覆盖虚拟函数,而不必实现另一个类
- 25. 准确的目的是什么做出反应DOM虚拟
- 26. 什么是做这个变量覆盖的正确方法?
- 27. 声明为“覆盖”的方法是否保持“虚拟”?
- 28. 虚拟覆盖和二进制兼容性
- 29. C++成员函数的虚拟覆盖和过载,同时
- 30. 什么是SQL Server中的覆盖索引和涵盖查询?
很好的解释! – Chris 2009-08-21 06:28:00
难道是vtable中的方法实际上被链接而不是被覆盖?我的目标是从覆盖方法,我们可以调用基地重写的方法。 – 2009-08-21 06:44:35
我认为链是隐含的继承。当你调用基本方法时,实际上是查找由基类定义的虚方法的定义并调用该方法。实际上,您可以查找基类的vtable并使用它。这就是为什么你需要使用base调用它,以便编译器知道去哪里看。 – paracycle 2009-08-21 07:01:01