2011-08-31 83 views
3

當它爲空時,是否可以檢測到Nullable類型(轉換爲對象)?檢測可空類型

由於Nullable<T>是一個真正的結構,我認爲它應該是可能的。

double? d = null; 
var s = GetValue(d); //I want this to return "0" rather than "" 

public string GetValue(object o) 
{ 
    if(o is double? && !((double?)o).HasValue) //Not working with null 
     return "0"; 
    if(o == null) 
     return ""; 
    return o.ToString(); 
} 
+0

如果接受'object'類型的參數的例程被傳遞了'Nullable '類型的變量,那麼例程將接收到一個空對象引用(如果該變量爲null)或者對' System.Double'(如果變量不是null)。它不會包含一個'Nullable '的實例。 – supercat

回答

5

http://msdn.microsoft.com/en-us/library/ms228597(v=vs.80).aspx

對象如果對象是 非空僅裝箱。如果HasValue爲false,那麼,而不是裝箱,將對象 引用簡單地分配給null。

如果對象非空 - 如果HasValue爲真 - 然後拳擊需要 的地方,但只有基礎類型的可空對象是基於是盒裝 。

所以你要麼有double要麼有null

public string GetValue(object o) 
{ 
    if(o == null) // will catch double? set to null 
     return ""; 

    if(o is double) // will catch double? with a value 
     return "0"; 

    return o.ToString(); 
} 
+0

所以答案是否定的,這是不可能的。感謝您的解釋。 – Magnus

+0

@Magnus但請記住Skeet告訴你的。有一種方法,但不是通過拳擊。最後,一切都取決於你想要做什麼。 – xanatos

5

對於每個Nullable類型,您都有方法GetValueOrDefault,是不是夠了?基於空類型

+0

因爲我在函數中使用'object',所以我需要將它轉換爲Nullable 才能使用該函數。 (在我的例子中) – Magnus

+1

你不需要你使用這個方法的函數,你可以執行GetDateOrDefault()。ToString() –

+0

Yeh,但這是一個適用於所有類型的通用格式化函數。我希望能夠檢測到所有爲空的Nullable數字類型,並返回「0」。 – Magnus

0

如果onull然後o is double?將是錯誤的。無論您的輸入參數的值如何,您的輸入參數值double? d

3

您的方法當前需要object,這意味着可以計數的值將被裝箱......並且將不再是可以爲空的值。 o的值將是或者是是不可爲空的類型的裝箱值或空引用。

如果可能的話,改變你的方法是通用的:

public string GetValue<T>(T value) 
{ 
    // Within here, value will still be a Nullable<X> for whatever type X 
    // is appropriate. You can check this with Nullable.GetUnderlyingType 
} 
+0

只是爲了更清楚地說明這一點,這意味着在內存中的null和盒式空可引用類型之間沒有區別。所以從方法中無法分辨出來。 – Iravanchi

+2

@Iravanchi:我會比這更強烈地說:根本不存在盒裝可空類型* *。裝箱可空類型值的結果是*或者*裝箱的不可空類型或空引用。 –

+0

感謝您的回答。不幸的是,對象在到達GetValue函數之前被裝箱,所以我不能使用你的通用示例。 – Magnus

-1

從我的理解,如果你想檢測是否有對象爲空,這可以很容易寫。

試試這個...

public static bool IsNullable(dynamic value) 
{ 
    try 
    { 
     value = null; 
    } 
    catch(Exception) 
    { 
     return false; 
    } 
    return true; 
} 

簡單!

+0

即使我們調用'IsNullable(5)','value = null'語句也會覆蓋'object'類型的存儲位置,而不是'int'類型。 – supercat

+0

你是對的。事後看來,我沒有仔細檢查過這個。理想情況下,最優雅的解決方案(至少在.net中)應檢查對象是否是類或結構,並確定對象的「可空性」。我相信我的理解是正確的,結構不能爲null,因爲它們是堆棧中存在的值類型,而類是存在於堆中的引用類型,因此是引用而不是絕對值。我要走開並進一步調查。 – series0ne

+0

.net中有三種可轉換爲「對象」的東西:可爲空的值類型,不可爲空的值類型和對象。請注意,值類型不是對象,即使每個不可爲空的值類型都具有可隱式轉換的關聯的「裝箱」對象類型,並且每個非空的可以爲null的值類型都可隱式轉換爲與其非關聯的對象類型 - 不可空當量。 C#將「派生」定義爲「從對象」派生出來的值類型,但是從其基類定義的其他繼承類類型來看,它們並不這樣做。 – supercat