很簡短的C#代碼,如下:
using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace 直接調度測試{ class Program { public class Father { public void DoWork() { Console.WriteLine("Father.DoWork()"); } public virtual void DoVirtualWork() { Console.WriteLine("Father.DoVirtualWork()"); } } public class Son : Father { public new void DoWork() { Console.WriteLine("Son.DoWork()"); } public override void DoVirtualWork() { Console.WriteLine("Son.DoVirtualWork()"); } public static void DoStaticWork() { Console.WriteLine("Son.DoStaticWork()"); } } static void Main(string[] args) { Father son2 = new Son(); // son2.DoVirtualWork(); son2.DoWork(); } }}
程序的輸出結果如下:
Son.DoVirtualWork()
Father.Dowork()
這里就有點迷糊了,哪位大俠給解釋下,十萬火急?。。。。。。。。。。?!
注:從CLR層面,膚淺的就不要了,謝謝!
7 回答

森林海
TA貢獻2011條經驗 獲得超2個贊
這答案誰告訴你的?有問題的。首先我覺得對方法表的理解有問題,每個類型都有自己的方法表,所以“Father類方法在方法表中位于Son方法的前面”這種說法有問題。CLR在調用一個方法時,已經知道這個方法是不是虛方法。如果不是虛方法,那么就去檢查變量類型的method table,因此son2.DoWork()查找的是Father的MT(如果找不到那么會去基類里找),找到了就執(zhí)行它(或者先JIT再執(zhí)行)。如果是虛方法,那么會根據引用找到堆上的那個對象,根據對象的type pointer找到對象的真正類型(即GetType方法的返回類型),因此son2.DoVirtualWork()會直接查找Son的MT(如果找不到那么就去基類,這跟非虛方法是相同的)。你可以看看CLR VIA C#,里面講的很清楚。

ibeautiful
TA貢獻1993條經驗 獲得超6個贊
//基類型
Father son2 = new Son();
//首先 檢查本類型(即Father)的方法DoVirtualWork,是不是虛或者抽象,如果不是//直接執(zhí)行;如果是,再看子類(即Son)有沒有重寫,如果重寫,則執(zhí)行子類方法,如//果沒有重寫,執(zhí)行本類型(即Father)的方法。
son2.DoVirtualWork();
//跟上面的規(guī)則一樣
son2.DoWork();

哈士奇WWW
TA貢獻1799條經驗 獲得超6個贊
這個主要是new 和override的問題
new 是把父類的方法隱藏了,你把基類隱式轉換成父類,調用的方法當然是父類的,因為是隱藏了,方法還在。
override 是把父類的方法重寫,覆蓋了,所以轉換成父類的時候,還是看不見父類的方法,只能調用子類的。
- 7 回答
- 0 關注
- 320 瀏覽
添加回答
舉報
0/150
提交
取消