[英]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
指令必須支持它:-)
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.