C# 繼承使用 :,IL 使用 extends。編譯器根據靜態類型決定呼叫前綴(yyy::abc 或 xxx::abc),但 callvirt 使實際調用取決於運行期物件類型。
// C# 代碼
class yyy { public virtual void abc() { Console.WriteLine("yyy abc"); } }
class xxx : yyy { public new void abc() { Console.WriteLine("xxx abc"); } }
IL:
yyy.abc:newslot virtual。xxx.abc:instance void abc()(無 virtual、無 newslot)。callvirt instance void yyy::abc() 呼叫,故輸出 yyy abc。若將變數宣告為 xxx a = new xxx(); a.abc();,編譯器會發出 call instance void xxx::abc(),輸出 xxx abc。這證明 new 僅影響編譯期繫結。
virtual + callvirt = 運行期多型。new = 編譯期靜態繫結隱藏。