簡體   English   中英

為什么顯式轉換為'decimal'會將顯式運算符調用為'long'?

[英]Why does an explicit cast to ‘decimal’ call an explicit operator to ‘long’?

請考慮以下代碼:

class Program
{
    public static explicit operator long(Program x) { return 47; }

    static int Main(string[] args)
    {
        var x = new Program();
        Console.WriteLine((decimal) x);
    }
}

令我驚訝的是,這產生了47 ; 換句話說,即使轉換為decimal也會調用explicit operator long

C#規范中是否有明確說明應該發生這種情況(如果是這樣,究竟在哪里)或者這是否是我遺漏的其他一些規則的結果?

我能想到的唯一解釋是編譯器足夠聰明,可以實現有一個隱式運算符,它將long轉換為十進制,當Program只能轉換為long時,它可以用來滿足Program和decimal之間的顯式轉換。

編輯:我們在這里; 數字類型之間的轉換內置於語言規范中:

6.1.2隱式數字轉換

隱式數字轉換是:

·從sbyte到short,int,long,float,double或decimal。

·從byte到short,ushort,int,uint,long,ulong,float,double或decimal。

·從short到int,long,float,double或decimal。

·從ushort到int,uint,long,ulong,float,double或decimal。

·從int到long,float,double或decimal。

·從uint到long,ulong,float,double或decimal。

· 從long到float,double或decimal。

·從ulong到float,double或decimal。

·從char到ushort,int,uint,long,ulong,float,double或decimal。

·從浮動到雙重。

從int,uint,long或ulong到float以及從long或ulong到double的轉換可能會導致精度損失,但絕不會導致數量級的損失。 其他隱式數字轉換永遠不會丟失任何信息。

char類型沒有隱式轉換,因此其他整數類型的值不會自動轉換為char類型。

因此,在程序和十進制之間進行轉換時,C#知道它可以隱式地從任何數字類型轉換為十進制,因此在執行此顯式轉換時,它將查找可以將程序轉換為數字類型的任何運算符。

有趣的是,如果您還將顯式轉換為uint,那么會返回48會發生什么? 編譯器選哪一個?

我找到了答案。 首先,有一種類型的概念被另一種類型所包含 ,在6.4.3用戶定義的轉換評估中定義如下:

如果從類型A到類型B存在標准隱式轉換(第6.3.1節),並且如果A和B都不是接口類型 ,那么A被認為包含在 B中,並且B被認為包含 A.

6.3.1標准隱式轉換表明“隱式數字轉換(第6.1.2節)”是標准隱式轉換, 6.1.2隱式數字轉換又定義了從longdecimal的隱式轉換。 因此, long 包含在 decimal

接下來, 6.4.5用戶定義的顯式轉換表明確定顯式轉換是否適用的其中一個階段是:

查找適用的用戶定義和提升轉換運算符集合U.此集合包含由D中的類或結構聲明的用戶定義和提升的隱式或顯式轉換運算符,這些運算符從包含或包含在S中的類型轉換為類型包含或包含在T.如果U為空,則轉換未定義,並發生編譯時錯誤。

這里, D指的是較早步驟的結果,在這種情況下,只包含decimalProgramobject 因此,集合U將包含我聲明的Program to- long顯式運算符,因為long包含在decimal (如前所述)。

接下來的步驟之一選擇long作為最具體的目標類型 TX

最后,同一算法的最后一步說明:

最后,應用轉換:

  • 如果S不是SX,則執行從S到SX的標准顯式轉換。
  • 調用最具體的用戶定義轉換運算符以從SX轉換為TX。
  • 如果TX不是T,則執行從TX到T的標准顯式轉換。

這里, SSX都是Program ,所以第一部分什么都不做。 選擇TXlongT為目標類型decimal ,因此最后一部分執行從longdecimal的標准轉換。

暫無
暫無

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

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