如果沒有關鍵字new或 override,默認使用的關鍵字就是new。在上面的類xxx的函數abc中,我們使用到了override關鍵字,它 暗示了這個函數abc覆寫了基類的函數。
IL默認調用對象所屬類的虛函數,並使用編譯期間的類型 。在這個例子中,它是yyy。
隨著在派生類中的覆寫而發生的第1個改變是,除函數原型外還會多 一個關鍵字virtual。之前並沒有提供new,因為函數new是和隔離於基類中的函數一起被創建的。
override的使用有效地實現了對基類函數的覆寫。這使得函數abc成為類xxx中的一個虛函數。換 句話說,override變成了virtual,而new則會消失。
因為在基類中有一個newslot修飾符,並且在 派生類中有一個具有相同名稱的虛函數,所以派生類會被調用。
在虛函數中,對象的運行期間類 型會被優先選擇。指令callvirt在運行期間解決了這個問題,而不是在編譯期間。
a.cs
class zzz
{
public static void Main()
{
yyy a = new xxx();
a.abc();
}
}
class yyy
{
public virtual void abc()
{
System.Console.WriteLine("yyy abc");
}
}
class xxx : yyy
{
public override void abc()
{
base.abc();
System.Console.WriteLine("xxx abc");
}
}
a.il
.method public hidebysig virtual instance void abc() il managed
{
ldarg.0
call instance void yyy::abc()
ldstr "xxx abc"
call void [mscorlib]System.Console::WriteLine(class System.String)
ret
}