国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

結合IL和Windbg來看.Net調用繼承虛方法的執行順序

2019-11-14 16:09:53
字體:
來源:轉載
供稿:網友

先上測試代碼:

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()");        }    }}
View Code

可能你對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了。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 边坝县| 花莲市| 若羌县| 沙河市| 长宁县| 个旧市| 孙吴县| 墨竹工卡县| 宁化县| 岚皋县| 合阳县| 聂荣县| 永德县| 修文县| 南雄市| 清流县| 林芝县| 南雄市| 喀喇沁旗| 金平| 乐至县| 阿鲁科尔沁旗| 阳城县| 丰都县| 阿鲁科尔沁旗| 北海市| 永和县| 怀远县| 凤翔县| 溆浦县| 神农架林区| 石景山区| 德化县| 灌南县| 容城县| 古交市| 长宁县| 顺平县| 蚌埠市| 安多县| 普洱|