2009-02-09 50 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>(); 

这将有助于避免对拆箱空引用代码合同警告。