2010-02-10 129 views
4

如上 - 有人知道一個double是否被隱式轉換爲double? (Nullable type)雙倍和雙倍?互換?

編輯:這裏究竟發生了什麼?

double d = 5;

double? d2 = d爲雙?

+0

請參閱http://msdn.microsoft.com/en-us/library/2cf62fcy.aspx和http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx – Brian 2010-02-10 23:55:14

+0

爲什麼不寫「雙? d = 1.0;「在你的IDE中,看看它是否編譯? – 2010-02-11 00:19:07

+0

從§6.1.4(隱式可空轉換):「對於從不可空值類型'S'轉換爲不可空值類型'T'的每個預定義隱式標識和數值轉換,以下隱式存在可爲空的轉換:[...]•從'S'到'T?'的隱式轉換。「 'double'扮演'S'角色,'double'扮演'T'的角色(都是不可空的),並注意到有一個從double('S')到'double'的隱式轉換'T'),通過上面的子句,存在從'double'('S')到'double?'('T?')的隱式轉換。 – jason 2010-02-11 03:22:25

回答

6

double d = 5; 
double? d2 = d as double?; 

那麼,讓我們通過它去。

在第一行中,您聲明瞭一個名爲d的類型爲double的局部變量。您爲其分配恆定的整數5。編譯器將常量整數5轉換爲雙精度值5.0,並生成將值分配給本地的代碼。

在第二行中,您聲明瞭一個名爲d2的局部變量double ?.

表達式「d as double?」相當於「d是double??(double?)d:(double?)null」,當然除了「d」只被評估一次。

讀取「d」的部分是雙倍的?「被評估爲真,因爲d被認爲是double類型的(當被問到」x是y「時,如果x是非空類型,而y是相應的可空類型,那麼結果總是爲真。)

編譯器知道這一點,因此丟棄替代「(雙?)空」,因此產生的代碼,就好像你說

double? d2 = (double?)d; 

這是產生通過調用雙?,傳球的構造在d中作爲構造函數的參數,並且將局部變量d2作爲「this」的引用。因此,本質上變成:

double? d2 = new Nullable<double>(d); 

那就是究竟是那裏發生了什麼。這一切都有道理嗎?

+0

Eric:當你這樣做的時候,編譯器不會抱怨嗎? d2 = d;?隱式強制轉換調用構造函數是否正常? – 2010-02-12 12:01:30

+0

@ChloeRadshaw:適用於涉及價值類型的轉化。你將int轉換爲double,我們構造一個新的double。當然,double的「構造函數」是IL中的單個指令,但這是一個實現細節。 – 2010-02-12 15:10:59

3

是的,double被隱式轉換爲double?。例如。如果ddouble那麼double? nullableD = d;是好的。

儘管double?未隱式轉換爲double。在這種情況下,您應該使用double d = nullableD.Value;

+0

您也可以使用強制轉換,但如果它爲空則會拋出異常。 – Brian 2010-02-10 23:48:59

+0

你應該只在使用nullableD.value之後檢查nullableD是否爲空。 – 2010-02-10 23:49:00

+0

@Paul:除非您對異常感到滿意,否則只需使用Value即可。 – 2010-02-10 23:50:58

17

它們根據您的標題不可互換。

有一個隱含double轉換爲double?

有一個明確轉換從double?double

這同樣適用於所有的空值類型真:有一個隱式轉換從TNullable<T>,並從Nullable<T>T明確的一個。

有趣的是,雖然Nullable<T>確實提供了這些轉化爲以正常的方式用戶定義的轉換,則MS C#編譯器不使用的那些 - 它調用Nullable<T>(T value)構造爲隱式轉換,並直接使用Value屬性爲反過來顯式轉換。

+0

@Jon:你下班或在家工作? :) – Perpetualcoder 2010-02-10 23:49:20

+0

@Perpetualcoder:現在是在英國下午11點50分 - 我即將上牀睡覺:) – 2010-02-10 23:50:33

+0

@Jon:在你碰到牀之前撿起幾百個代表點:) – Perpetualcoder 2010-02-10 23:58:08

2

,您可以在如下

double? d; 
    d = 12.00  
    double d2 = (double)d; 

小心你投爲雙過嗎?可能爲null;究竟這是怎麼回事就更好做此項檢查


if(d.HasValue) 
    { double d2 = (double)d; } 
+1

只有手動檢查值是否爲空而不是由於錯誤或其他某種情況應該引起異常。 – 2010-02-10 23:51:45