2013-07-23 40 views
4

我創建了一個類動態(發現它here),但我不明白爲什麼我不能用它來創建一個列表?爲什麼我不能使用myObject創建一個List <>?

var myType = CompileResultType(); 
var myObject = Activator.CreateInstance(myType); 
var myList = new List<myObject>(); 

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

我應該怎麼做?

+4

它們被稱爲泛型*類型*參數,因爲它們期望類型,而不是實例。所以你需要知道實際的類型或者用反射來創建列表對象。 =) –

+0

@ J.Steen你應該添加它作爲答案';)' –

+0

你會這麼好以糾正我的片段? :) – yonan2236

回答

8

它們被稱爲泛型類型參數,因爲它們期望類型,而不是實例。所以你需要知道實際的類型或者用反射來創建列表對象。

Type listType = typeof(List<>); 
Type dynamicClassType = listType.MakeGenericType(myObject.GetType()); 
object myList = Activator.CreateInstance(dynamicClassType); 

但是,您無法使用例如以任何有意義的方式,因爲它是一個對象。

  • Avner Shahar-Kashtan's answer建議你可以將其轉換爲IList和使用非通用的方法。

    IList myList = (IList)Activator.CreateInstance(dynamicClassType); 
    
  • 你也可以通過反射調用list-instance的方法。

    // roughly 
    MethodInfo addMethod = myList.GetType().GetMethod("Add"); 
    addMethod.Invoke(myList, objectToAdd); 
    
  • 或做在Cuong Le's answer建議,並使用dynamic爲列表實例的類型。

    dynamic myList = Activator.CreateInstance(dynamicClassType); 
    
0

分析:

這裏的問題是,你動態創建一個類型,你有沒有編譯時類型名稱來引用它。但是,泛型要求使用類型名稱。

假設你想要一個List<string>string是靜態確定的類型名稱;你不會首先聲明一個變量,如string foo;,然後將你的列表聲明爲List<foo> ......你會嗎?

就像foomyObject不是一個類型名稱—這是引用您的動態類型—的對象的變量的名稱,因此,你不能把它作爲一個泛型類型參數。同樣,List<myType>也不會工作,因爲myType也不是一個類型名稱;它只是一個引用Type對象的變量。

建議:

如果你想想看,使用泛型這裏根本不會有幫助,因爲使用泛型將無法提高靜態類型安全。改爲使用ArrayList

2

泛型類型需要一個類型類,而不是實例,也許你需要:

var myType = CompileResultType(); 
var listType = typeof (List<>).MakeGenericType(myType); 
var myList = Activator.CreateInstance(listType); 
在這裏

myListobject,如果你想添加或列表中刪除項,你應該利用dynamic

dynamic myList = Activator.CreateInstance(listType); 

所以你可以撥打:

myList.Add(...); 
0

您與類型,不實例工作。假設CompileResultType()返回MyType

MyType myType = CompileResultType(); 
List<MyType> list = new List<MyType>(); 

我不知道爲什麼你使用Activator.CreateInstance()雖然...

6

爲了動態地構造一個泛型類型,你將不得不使用反射,特別方法MakeGenericType。事情是這樣的:我定義爲myListIList,因爲我們沒有爲它編譯時類型

Type baseListType = typeof(List<>); // get the generic List<> 
Type myType = CompileResultType; // same as in yours. 
Type myListType = baseListType.MakeGenericType(myType); // Get the List<MyType> 
IList myList = (IList)Activator.CreateInstance(myListType); // Instantiate. 

通知。幸運的是,我們有便利的基類和接口,如IListIEnumerableList<T>實現的其他幾個接口,我們可以使用它們。

1

這將創建列表List<WhatEverIsInMyType>類型:

var listType = typeof(List<>).MakeGenericType(myType); 

現在你需要創建一個實例,但你已覆蓋:

var list = Activator.CreateInstance(listType); 

不幸的是,我們使用的是反射所以確切類型未知在編譯時但不是全部丟失,您可以使用非泛型類型:

var list = (IList)Activator.CreateInstance(listType); 

現在你可以使用像AddRemove這樣的方法來使用你的列表,但要小心,因爲如果類型不算數學,你將得到運行時異常。

相關問題