2015-12-30 163 views
5

我有一個驚人的醜陋的方法,應該從數據庫中提取各種數據,並使用它構造一個請求類型的對象。我們的目標是把各種醜陋的東西整合到一個地方,以便從包含這種方法的類中派生的類可以相對乾淨。當返回類型是通用接口時如何將對象轉換爲泛型返回類型?

我並沒有當它應該返回一個對象,即使類型爲空一個問題

protected T getValue<T>(ParameterObject myParameterObject) 
{ 
    var typeOfT = typeof (T); 

    if (typeOfT == typeof(bool)) 
    { 
     string val = this.getValue(myParameterObject); 

     if (val == null) 
      return default(T); 

     bool rVal; 
     if (!Boolean.TryParse(val, out rVal)) 
      return default(T); 

     return changeType<T>(rVal); 
    } 

    if (typeOfT == typeof (double?)) 
    { 
     string val = this.getValue(myParameterObject); 

     if (val == null) 
      return default(T); 

     double rVal; 
     if (!Double.TryParse(val, out rVal)) 
      return default(T); 

     return changeType<T>(rVal); 
    } 

    [...] 
} 

public static T changeType<T>(object value) 
{ 
    var t = typeof(T); 
    if (!t.IsGenericType || t.GetGenericTypeDefinition() != typeof(Nullable<>)) 
     return (T)Convert.ChangeType(value, t); 

    if (value == null) 
     return default(T); 

    t = Nullable.GetUnderlyingType(t); 
    return (T)Convert.ChangeType(value, t); 
} 

不幸的是,我在我想要的返回類型爲IList的,其中病例我想返回一個列表:

protected T getValue<T>(ParameterObject myParameterObject) 
{ 
    var typeOfT = typeof (T); 

    if (typeOfT.IsGenericType) 
    { 
     if (typeOfT.GetGenericTypeDefinition() == typeof (IList<>)) 
     { 
      var genericArgumentType = typeOfT.GenericTypeArguments.FirstOrDefault(); 
      var baseType = typeof (List<>); 
      var genericType = baseType.MakeGenericType(new[] {genericArgumentType}); 

      var rVal = Activator.CreateInstance(genericType); 

      [code to populate the list] 

      return changeType<T>(rVal); 
     } 

    [...] 
} 

我不能返回RVAL,因爲它是一個對象,而不是T的實例,但我一changeType()函數失敗,一個錯誤:

System.InvalidCastException: Object must implement IConvertible.

所以,我有一個返回類型爲IList的泛型方法,並且我有一個List對象,但是我對它的引用是Object類型的。我如何施放它以便我可以從函數中返回它?

+2

對不起,如果我錯過了一些顯而易見的東西,但爲什麼你要做'return changeType (rVal);'而不是'return(T)(object)rVal;'? – 31eee384

回答

1

您的return (T)Convert.ChangeType(value, t);行失敗,因爲您的value對象不執行IConvertible

MSDN docs

[...] For the conversion to succeed, value must implement the IConvertible interface, because the method simply wraps a call to an appropriate IConvertible method. The method requires that conversion of value to conversionType be supported.

爲了解決這個問題,我不知道的一般方法,但對於value作爲一個IEnumerableIEnumerable<>類型的具體情況,那麼你可以嘗試施放然後進行value.Select(x => changeType<ListGenT>(x)) linq查詢。通過遞歸地使用changeType方法,它也應該處理嵌套泛型類型。

+0

我仍然不確定我的理解,但是如果我將我的方法更改爲返回列表,而不是創建列表並返回IList ,問題就消失了。 –