通過 Windbg 觀測 .NET 運行時,揭示虛方法多態調用的底層機制:MethodTable 佈局、偏移量固定、調用指令序列。驗證繼承、覆寫、隱藏(new)對表結構的影響。
class Base {
virtual void VirtualFun1();
void NoneVirtualFun1();
virtual void VirtualFun2();
virtual void VirtualFun3();
}
class Derived : Base {
override void VirtualFun1();
new virtual void VirtualFun2(); // 隱藏
virtual void VirtualFun4(); // 新增
}
Object 虛方法(ToString、Equals、GetHashCode、Finalize)。Base 三個虛方法(VirtualFun1/2/3)。NoneVirtualFun1 + 默認構造函數。VirtualFun1 覆寫 → 槽 4 指向 Derived 實現。VirtualFun2 隱藏(new)→ 不覆蓋槽 5,基類實現保留;新增槽 7 指向 Derived.VirtualFun2。VirtualFun4 新增 → 追加槽 8。Base b = new Derived();
b.VirtualFun1(); // 調用 Derived 實現
; 編譯生成匯編
mov ecx, esi ; 對象引用
mov eax, [ecx] ; MethodTable 指針
call dword ptr [eax + 3Ch] ; 偏移量 3Ch 對應 VirtualFun1 槽
關鍵點:偏移量 3Ch 在整個繼承鏈中固定不變。Base 與 Derived 的 MethodTable 槽 4 位置相同,指向不同實現,由此實現多態。
對象 -> MethodTable -> 固定偏移量 定位具體方法實現,完成多態分派。