先上测试代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks; namespace TestVirt
{
class Program
{
static void Main(string[] args)
{
A c1 = new C();
c1.Foo(); C c2 = new C();
c2.Foo(); Console.ReadLine();
}
} class A
{
public virtual void Foo()
{
Console.WriteLine("Call on A.Foo()");
}
} class B : A
{
public override void Foo()
{
Console.WriteLine("Call on B.Foo() ");
}
} class C : B
{
public new void Foo()
{
Console.WriteLine("Call on C.Foo()");
}
}
}

可能你对C c2 = new C();这个的结果没有什么疑问,但是对A c1 = new C();的结果百思不解。呵呵,我们慢慢来看这个区别,先来看看最终的IL代码是什么样子的:

.method private hidebysig static void  Main(string[] args) cil managed
{
.entrypoint
// 代码大小 34 (0x22)
.maxstack 1
.locals init ([0] class TestVirt.A c1,
[1] class TestVirt.C c2)
IL_0000: nop
IL_0001: newobj instance void TestVirt.C::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: callvirt instance void TestVirt.A::Foo()
IL_000d: nop
IL_000e: newobj instance void TestVirt.C::.ctor()
IL_0013: stloc.1
IL_0014: ldloc.1
IL_0015: callvirt instance void TestVirt.C::Foo()
IL_001a: nop
IL_001b: call string [mscorlib]System.Console::ReadLine()
IL_0020: pop
IL_0021: ret
} // end of method Program::Main

  

根据IL的结果,我们明显可以看到,两次调用不同的地方就在于一个是Call的A的Foo,一个是C的Foo。

但是这里你注意了:我们new的是同样的一个对象,他们具有同样的内存布局。

用WinDbg来看看我们new出来对象的MethodTable是长什么样子的吧:

看到没有,这个C对象的方法表里面同时包括了C自己定义的Foo和上一层次父对象的Foo方法。

结合IL的结果和C对象的方法表的Dump结果,相信看官已经明白为啥两次调用为啥会用不同了吧。

算了,还是简单描述一下吧:首先根据il的结果明显两次调用请求的方法是不同的;其次,你可以看到我们的C对象引用的方法表里面确实有两个Foo方法。

呵呵,这样同样类型的对象对不同方法调用的请求是不是就可以分开了呢?当然是!

PS:可能会有人问:为啥我请求的A.Foo()你这个MethodTable里面没有呢?

脑补下吧哥:被B给override了。

最新文章

  1. 如何创建一个简单的Visual Studio Code扩展
  2. VSS 的修复和扫描
  3. 3-python学习——变量
  4. 【JavaScript】JQuery中$.fn、$.extend、$.fn.extend
  5. 用序列化工具写入xml
  6. Python list 常用操作
  7. DIV+CSS两种盒子模型
  8. JS继承,原型继承,构造函数的继承,非构造函数"的继承
  9. POJ 1279 Art Gallery 半平面交求多边形核
  10. public private proteccted区别
  11. 新概念英语(1-23)Which glasses?
  12. Python中byte与str
  13. 英语-TOEFL和GRE复习计划与资料
  14. There is no getter for xxx 或者 will not be managed by Spring 解决
  15. Netty入门(三)之web服务器
  16. 判断ie浏览器7、8、9三个版本
  17. MVC实战之排球计分(六)—— 使用EF框架,创建Controller,生成数据库。
  18. python os详解
  19. DAY8-Python学习笔记
  20. JavaScript与DOM(下)

热门文章

  1. sqlite3使用备忘
  2. 循环队列(Joseplus Problem)
  3. 【转】PHP微信上传永久图片素材
  4. DOS下修改IP地址
  5. CF581B Luxurious Houses 模拟
  6. CF796B Find The Bone
  7. react常用开发工具
  8. JavaBean简介和用法
  9. for别名
  10. TP框架中D方法和M方法