2014-01-08 231 views
5

我正在嘗試做一個簡單的測試,其中我將兩個通用對象傳遞給測試函數,看看它們是否可以轉換爲List<S>,並進一步檢查計數的名單是平等的。Can not cast a generic type to list in C#

下面的代碼工作:

private static void Test<T> (T obj1, T obj2) { 
    if (typeof(T).IsGenericType) { 
     var genericTypeParam1 = typeof(T).GetGenericArguments().First(); 
     Console.WriteLine(genericTypeParam1); 

     // LINE MARKER 1 
     // var obj1AsList = (obj1 as IEnumerable<genericTypeParam1>); 
    } 
} 

static void Main(string[] args) { 
    Test(Enumerable.Range(0, 5).ToList(), Enumerable.Range(0, 5).ToList()); 
    Console.ReadLine(); 
} 

但是,如果我去掉打上LINE MARKER 1行了,我得到以下錯誤:

The type or namespace name 'genericTypeParam1' could not be found (are you missing a using directive or an assembly reference?) 

我不事先知道,測試將得到List小號。但我的意圖是先檢查是否obj1obj2可以作爲表,然後預先比較

var obj1AsList = obj1 as List<genericTypeParam1>; 
var obj2AsList = obj2 as List<genericTypeParam1>; 
var flag = (obj1AsList != null) && (obj2AsList != null) && (obj1AsList.Count() == obj2AsList.Count()); 

感謝您的幫助。

+1

測試<給出類型這裏>(Enumerable.Range(0,5 ).ToList(),Enumerable.Range(0,5).ToList());你錯過了類型 – DevEstacion

+1

@RonaldEstacion這不是問題。這將由編譯器推斷。 – MarcinJuraszek

+0

在你的示例代碼中,你表明你想轉換爲'IEnumerable'而不是'IList',這是否正確?只有後者纔有'Count'屬性,可以通過轉換到非泛型'Collections'接口來訪問它。 (見下面的答案)。 – nicholas

回答

1

如果真正的目標是確保這兩個項目都可以轉換爲某種通用列表類型,那麼只需將這些對象轉換爲非通用接口即IList接口。然後,你可以比較計數:

private static bool Test<T>(T obj1, T obj2) 
{ 
    if (typeof(T).IsGenericType) 
    { 
     var obj1List = obj1 as System.Collections.IList; 
     var obj2List = obj2 as System.Collections.IList; 

     if (obj1List != null && obj2List != null && obj1List.Count == obj2List.Count) 
      return true; 
    } 
    return false; 
} 

如果你真的想使用反射它,你可能會做出這樣的工作:

if (typeof(T).IsGenericType) { 
     var genericTypeParam1 = typeof(T).GetGenericArguments().First(); 
     Console.WriteLine(genericTypeParam1); 

     // LINE MARKER 1 
     // var obj1AsList = (obj1 as IEnumerable<genericTypeParam1>); 
     var genericListType = typeof(IEnumerable<>).MakeGenericType(genericTypeParam1); 

     Convert.ChangeType(obj1,genericListType); 
    } 
+0

非常感謝。我正在使用第一個建議。第二個在'Convert.ChangeType'處引發一個'InvalidCastException',表示'Object必須實現IConvertible'。 – Shredderroy

2

提供爲泛型類型參數的類型必須在編譯時已知。你試圖通過Type類型變量,這就是爲什麼你得到編譯類型錯誤。

你可以讓一個事實,即只有List<T>實例可以作爲方法參數傳遞在編譯時檢查由編譯器:

private static void Test<T>(List<T> obj1, List<T> obj2) 
{ 
    var flag = obj1 != null && obj2 != null && obj1.Count == obj2.Count; 
} 

如果您希望測試完成運行時,你應該使用的解決方案提供埃裏克。

4

I am trying to do a simple test, in which I pass in two objects to a test function, see if they can be cast to List<S> , and further, check if the counts of the lists are equal.

正確的方式做到這一點是:

static bool Test<T>(object obj1, object obj2) 
{ 
    List<T> list1 = obj1 as List<T>; 
    List<T> list2 = obj2 as List<T>; 
    return list1 != null && list2 != null && list1.Count == list2.Count; 
} 
... 
bool result = Test<int>(Enumerable.Range(0, 5).ToList(), Enumerable.Range(0, 5).ToList()); 

這需要兩個對象和類型,如果對象是該類型的大小相等的名單返回true。

+0

非常感謝你。我已經接受尼古拉斯的答案,因爲它也提出了第二種方法。但我基本上使用的東西與您的建議非常相似。 – Shredderroy

相關問題