程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> 關於C語言 >> 《C# to IL》第四章 關鍵字和操作符(上)(12)

《C# to IL》第四章 關鍵字和操作符(上)(12)

編輯:關於C語言

在上面程序的上下文中,我們要向C#新手多做一點解釋。

我們能夠使基類的一個對象和派生類xxx的一個對象相等。我們調用了方法a.abc()。隨之出現的 問題是,函數abc的下列2個版本,哪個將會被調用?

l 出現在基類yyy中的函數abc,調用對象屬 於這個函數。

l 函數abc存在於類xxx中,它會被初始化為這個類型。

換句話說 ,是編譯期間類型有意義,還是運行期間的類型有意義?

基類函數具有一個名為virtual的修飾符 ,暗示了派生類能覆寫這個函數。派生類,通過添加修飾符new,通知編譯器——這個函數abc 與派生類的函數abc無關。它會把它們當作單獨的實體。

首先,使用ldloc.0把this指針放到棧上 ,而不是使用call指令。這裡有一個callvirt作為替代。這是因為函數abc是虛的。除此之外,沒有區別 。類yyy中的函數abc被聲明為虛的,還被標記為newslot。這表示它是一個新的虛函數。關鍵字new位於C# 的派生類中。

IL還使用了類似於C#的機制,來斷定哪個版本的abc函數會被調用。

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()
{
System.Console.WriteLine("xxx abc");
}
}

a.il

.assembly mukhi {}
.class private auto ansi zzz extends [mscorlib]System.Object
{
.method public hidebysig static void vijay() il managed
{
.entrypoint
.locals (class yyy V_0)
newobj     instance void xxx::.ctor()
stloc.0
ldloc.0
callvirt   instance void yyy::abc()
ret
}
}
.class private auto ansi yyy extends [mscorlib]System.Object
{
.method public hidebysig newslot virtual instance void abc() il managed
{
ldstr      "yyy abc"
call       void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
}
.class private auto ansi xxx extends yyy
{
.method public hidebysig virtual instance void abc() il managed
{
ldstr      "xxx abc"
call       void [mscorlib]System.Console::WriteLine(class System.String)
ret
}
.method public hidebysig specialname rtspecialname instance void .ctor() il managed
{
ldarg.0
call instance void yyy::.ctor()
ret
}
}

Output

xxx abc

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved