2010-10-08 50 views
7

假設我有一個直到運行時才知道的類。 在運行時,我得到一個類型爲Foo.GetType()的引用x。 只能使用x和列表<>,我可以創建一個Foo類型的列表嗎?如何實例化列表<T>但T直到運行時才知道?

如何做到這一點?

+3

任何阻止你簡單創建一個'List '? – Flynn1179 2010-10-08 07:10:51

+0

@ Flynn1179,讓我看看你是如何做到的。 – xport 2010-10-08 07:13:11

+0

'List myList = new List ();' – Flynn1179 2010-10-08 07:59:06

回答

19
Type x = typeof(Foo); 
Type listType = typeof(List<>).MakeGenericType(x); 
object list = Activator.CreateInstance(listType); 

當然你不要指望在這裏的任何類型的安全性所產生的名單編譯時爲object。使用List<object>會更實用,但仍然受限於類型安全性,因爲只有在運行時才知道Foo的類型。

+0

不錯!你的回答也(正確地)表明,使用這樣的清單將是非常不安全的。當然,我們可以聲明'list'是一個(非泛型)類型的'IList'或'ICollection'(而不是'object'),並伴隨着一個相應的'Activator.CreateInstance'類型的返回值,因此使用'list'作爲集合的有限方式成爲可能。 – stakx 2010-10-08 07:22:35

+2

如果您在運行時創建類型,請確保不存在任何編譯時類型安全性。 – Frank 2010-10-08 07:26:15

0

事情是這樣的:

Activator.CreateInstance(typeof運算(名單<>)MakeGenericType(類型)。)

11

當然,您可以:

var fooList = Activator 
    .CreateInstance(typeof(List<>) 
    .MakeGenericType(Foo.GetType())); 

這裏的問題是,fooList是類型爲object,因此您仍然必須將其轉換爲「可用」類型。但是這種類型會是什麼樣子?作爲數據結構支撐添加和仰視型TList<T>(或更確切地說IList<>)的對象中T不協變,所以你不能施放List<Foo>List<IFoo>其中Foo: IFoo。你可以將它投射到IEnumerable<T>,它在T中是協變的。

如果您使用的是C#4.0中,你也可以考慮鑄造fooListdynamic這樣你至少可以使用它作爲一個列表(例如添加,查找和刪除對象)。

考慮到所有這些以及事實,在運行時無論如何創建類型時都沒有任何編譯時類型安全性,只需使用List<object>就可能是這種情況下最好/最實用的方法。

相關問題