2016-09-22 61 views
1

在一个声明中铸造我有一个小工具方法,看起来像这样:拆箱和泛型方法

/// <summary> 
/// Replaces a DBNull value with the default of the type specified 
/// </summary> 
/// <typeparam name="T">Resulting type</typeparam> 
/// <param name="p_this">Object to check for DBNull</param> 
/// <returns>p_this if it is not DBNull.Value, else default(T)</returns> 
public static T ReplaceDBNullWithDefault<T>(this object p_this) 
{ 
    return p_this == System.DBNull.Value ? default(T) : (T)p_this; 
} 

在我的特定情况下,我拿着一个记录了一个数据表,并采取特定领域使用弱类型,我得到的具体领域是一个long这是被装箱到object。再现这样的一个例子是如下:

var obj = 2934L; 
int num = obj.ReplaceDBNullWithDefault<int>(); 

它失败并InvalidCastException,在(T)p_this

我明白为什么,盒装long不能直接转换为int,并试图像这样做也失败:

object myLong = 234L; 
int myInt = (int)myLong; 

然而,拆箱,然后浇注工作正常:

object myLong = 234L; 
int myInt = (int)(long)myLong; 

如何在我的方法中解决此问题?

+0

难道你的理由阐述为什么你铸造'int',而不是'long'? (因此将'T'指定为'long') –

+0

通过提供正确的类型;) –

+0

我将结果放入的字段是“int”,而不是“long”。我想我可以在那里演出。 – Logan

回答

0

你可以试试这个:

public static T ReplaceDBNullWithDefault<T>(this object p_this) where T : struct 
{ 
    return 
     p_this == System.DBNull.Value 
      ? default(T) 
      : (T)Convert.ChangeType(p_this, typeof(T)); 
} 

不过,如果您尝试此功能适用于未兑换的型,你会得到一个异常。

所以可能它真的会更好地将值手动转换为已知类型。

0

您可以使用此方法:

/// <summary> 
/// Replaces a DBNull value with the default of the type specified 
/// </summary> 
/// <typeparam name="T">Resulting type</typeparam> 
/// <param name="value">Object to check for DBNull</param> 
/// <param name="tryConvert">if true the object will be converted to the target type if possible, otherwise an InvalidCastException is raised</param> 
/// <returns>p_this if it is not DBNull.Value, else default(T)</returns> 
/// <exception cref="InvalidCastException">Thrown if the target type is incorrect and the value could not be converted to it</exception> 
public static T ReplaceDbNullWithDefault<T>(this object value, bool tryConvert = true) 
{ 
    if (value == System.DBNull.Value || value == null) 
     return default(T); 
    if (value is T) 
     return (T) value; 
    if(!tryConvert || !(value is IConvertible)) 
     throw new InvalidCastException($"Cannot convert {value.GetType()} to {typeof(T)}."); 
    return (T)((IConvertible) value).ToType(typeof(T), null); 
}