2016-09-22 58 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); 
}