2009-02-09 53 views

回答

64

拆箱僅在類型相同的情況下才有效!您不能解除不包含目標值的object。你需要的是沿

decimal tmpvalue; 
decimal? result = decimal.TryParse((string)value, out tmpvalue) ? 
        tmpvalue : (decimal?)null; 

這看起來值是否可解析爲decimal線的東西。如果是,則將其分配給result;否則分配null。下面的代碼做大致相同,可能會更容易理解人們不熟悉的條件運算符?:

decimal tmpvalue; 
decimal? result = null; 
if (decimal.TryParse((string)value, out tmpvalue)) 
    result = tmpvalue; 
+2

我不會在這裏使用「相同」這個詞。例如,你可以在枚舉類型和它們的基礎類型T和T?以及其他一些奇怪的IIRC之間取消裝箱。 CLR比人們所期望的更寬鬆。 – 2009-02-09 09:42:38

+0

(但是,是的,你不應該期望拆箱解析一個字符串:) – 2009-02-09 09:43:09

+0

@Jon:你有更好的公式?由於缺乏這一點,我會將您的評論複製到我的答案中,因爲它很好地表達了警告。 – 2009-02-09 09:58:28

2

,如果你使用decimal? temp = (decimal?)value;

5

你應該解析小數。但是,如果你希望你的十進制數爲空當字符串是不正確的,使用的TryParse:

decimal parsedValue; 
decimal? temp = decimal.TryParse(value, out parsedValue) 
       ? value 
       : (decimal?)null; 

這樣你就可以避免異常在解析生病格式化字符串。

幾乎所有的基元類型都提供了一個Parse和TryParse方法來從字符串轉換。

也建議將提供者參數的文化傳遞給該方法以避免小數點分隔符出現問題。如果您正在閱讀另一個系統,CultureInfo.InvariantCulture可能是要走的路(但它不是默認設置)。

bool TryParse(string s, NumberStyles style, 
    IFormatProvider provider, out decimal result) 
1

如果你不想來解析字符串,但希望確保您收到null,一個decimal或可爲空decimal,那麼你可以做這樣的事情:

public static Nullable<T> Convert<T>(object input) 
    where T : struct 
{ 
    if (input == null) 
     return null; 
    if (input is Nullable<T> || input is T) 
     return (Nullable<T>)input; 
    throw new InvalidCastException(); 
} 

你可以使它在最後一行返回null,而不是如果你想避免異常,雖然這不會區分實際的空值和壞的強制轉換。

請注意,您必須使用「is」運算符,因爲「as」運算符不適用於值類型,並且未經檢查而投射可能會引發InvalidCastException。

你也可以把它的擴展方法:

public static class ObjectExtensions 
{ 
    public static Nullable<T> ToNullable<T>(this object input) 
     where T : struct 
    { 
     if (input == null) 
      return null; 
     if (input is Nullable<T> || input is T) 
      return (Nullable<T>)input; 
     throw new InvalidCastException(); 
    } 
} 

而且使用這樣的:

object value = 123.45m; 
decimal? dec = value.ToNullable<decimal>(); 

這將有助於避免對拆箱空引用代碼合同警告。