2010-10-08 25 views
7

Giả sử tôi có một lớp chưa được biết cho đến khi chạy. Khi chạy, tôi nhận tham chiếu, x, thuộc loại Kiểu tham chiếu đến Foo.GetType(). Chỉ bằng cách sử dụng x và Danh sách <>, tôi có thể tạo danh sách loại Foo không?Làm thế nào để khởi tạo Danh sách <T> nhưng T là không biết cho đến khi chạy?

Làm cách nào để thực hiện điều đó?

+3

Mọi thứ dừng bạn chỉ cần tạo một 'Danh sách '? – Flynn1179

+0

@ Flynn1179, hãy để tôi xem cách bạn làm điều đó. – xport

+0

'Danh sách myList = Danh sách mới ();' – Flynn1179

Trả lời

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

Tất nhiên bạn không nên mong đợi bất kỳ sự an toàn loại ở đây là danh sách kết quả là của loại object tại thời gian biên dịch. Sử dụng List<object> sẽ thực tế hơn nhưng vẫn bị hạn chế về loại an toàn vì loại Foo chỉ được biết khi chạy.

+0

Đẹp! Câu trả lời của bạn cũng cho thấy (chính xác) rằng làm việc với một danh sách như vậy sẽ khá loại-không an toàn. Tất nhiên, người ta có thể khai báo 'list' như là một kiểu (không chung chung)' IList' hoặc 'ICollection' (thay vì chỉ' đối tượng'), kèm theo một đoạn tương ứng của 'Activator.CreateInstance' giá trị, để một cách hạn chế làm việc với 'list' như một bộ sưu tập có thể trở thành có thể. – stakx

+2

Nếu bạn tạo các kiểu khi chạy, chắc chắn không thể có bất kỳ sự an toàn kiểu thời gian biên dịch nào. – Frank

0

Something như thế này:

Activator.CreateInstance (typeof (Danh sách <>) MakeGenericType (loại).)

11

Chắc chắn bạn có thể:

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

Vấn đề ở đây là rằng fooList là thuộc loại object, do đó bạn vẫn sẽ phải truyền đến loại "có thể sử dụng". Nhưng loại này sẽ như thế nào? Là cấu trúc dữ liệu hỗ trợ thêm và tìm kiếm các đối tượng thuộc loại TList<T> (hoặc thay vì IList<>) không phải là biến thể trong T để bạn không thể đúc List<Foo> đến List<IFoo> nơi Foo: IFoo. Bạn có thể truyền nó đến một số IEnumerable<T> là biến thể trong T.

Nếu bạn đang sử dụng C# 4.0, bạn cũng có thể cân nhắc việc đúc fooList thành dynamic để ít nhất bạn có thể sử dụng nó làm danh sách (ví dụ: thêm, tra cứu và xóa đối tượng).

Xem xét tất cả điều này và thực tế là bạn không có bất kỳ kiểu thời gian biên dịch nào khi tạo kiểu bất kỳ lúc nào, chỉ cần sử dụng List<object> có lẽ là cách tốt nhất/thực dụng nhất trong trường hợp này.

Các vấn đề liên quan