簡體   English   中英

C#編譯器如何處理重載顯式轉換運算符?

[英]How does the C# compiler handle overloading explicit cast operators?

編譯器應該翻譯這段代碼:

public static explicit operator Int64(MyNumber n)
{
    return n.ToInteger();
}

public static explicit operator Double(MyNumber n)
{
    return n.ToDouble();
}

兩個方法具有相同的名稱和簽名,但只有它們的返回類型不同,例如

public static Int64 ExplicitCast(MyNumber n)
...

public static Double ExplicitCast(MyNumber n)
...

但是,我們不允許只有返回類型的方法。 窗簾背后會發生什么?

從技術上講,CLS(公共語言規范,指定所有.NET語言應該支持的.NET虛擬機的子部分的規范)表示顯式op_Explicit方法的名稱應該是op_Explicit (參見例如http:// goo .gl / wn8dHq )。

您不能擁有多個具有相同名稱且只有不同返回類型的方法的限制是C#的限制。 IL語言(即.NET虛擬機的語言)沒有此限制。

例如,請參閱: https//stackoverflow.com/a/442100/613130

但是,某些語言(例如MSIL)允許通過返回類型進行重載。 他們當然也面臨上述困難,但他們有解決方法,你必須查閱他們的文檔。

https://blogs.msdn.microsoft.com/abhinaba/2005/10/07/c-cil-supports-overloading-by-return-type/

但是,CIL確實支持通過返回類型重載方法,即使C#,VB沒有。 實現轉換運算符重載C#編譯器使用此功能(我知道一種用法,我確信還有更多:))

(這就是這里提到的情況)

如果您想查看ECMA-335標准:

I.8.11.1方法定義

方法簽名定義了調用約定,方法的參數類型以及方法的返回類型

如果您有興趣知道如何調用該方法......那么......很明顯,如果IL語言支持返回類型的重載,那么它的call指令必須支持它:-)

例如http://goo.gl/CS4FPb

call int64 MyNumber::op_Explicit(class MyNumber)

VS

call float64 MyNumber::op_Explicit(class MyNumber)

請注意,CLS通常僅根據返回類型禁止重載...但它有一個異常的op_Implicit (隱式轉換運算符)和op_Explicit (顯式轉換運算符)(來自相同的ECMA-335文件):

CLS規則38:屬性和方法可以僅根據其參數的數量和類型進行重載,但名為op_Implicit和op_Explicit的轉換運算符除外,它們也可以根據其返回類型進行重載。

我不確定你問題的目的,所以這是我能給你的最佳答案。 上面的代碼編譯成這樣的東西

MyNumber.op_Explicit:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  callvirt    UserQuery+MyNumber.ToInteger
IL_0007:  stloc.0     
IL_0008:  br.s        IL_000A
IL_000A:  ldloc.0     
IL_000B:  ret         

MyNumber.op_Explicit:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  callvirt    UserQuery+MyNumber.ToDouble
IL_0007:  stloc.0     
IL_0008:  br.s        IL_000A
IL_000A:  ldloc.0     
IL_000B:  ret      

它看起來“不一致”的原因是因為關鍵字explicit operator 它告訴編譯器生成代碼的方式與在顯式轉換中的方式不同。

沒有它,你會得到這樣的東西:

MyNumber.Double2:
IL_0000:  nop         
IL_0001:  ldarg.0     
IL_0002:  callvirt    UserQuery+MyNumber.ToDouble
IL_0007:  stloc.0     
IL_0008:  br.s        IL_000A
IL_000A:  ldloc.0     
IL_000B:  ret    

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM