2010-03-22 20 views
5

Tôi đang thử một chút phản ánh và có câu hỏi về cách truyền đối tượng kết quả đến một IList.C# - Đối tượng truyền tới IList <T> dựa trên Loại

Đây là sự phản ánh:

private void LoadBars(Type barType) 
{ 
    // foo has a method that returns bars 
    Type foo = typeof(Foo); 

    MethodInfo method = foo.GetMethod("GetBars") 
     .MakeGenericMethod(bar); 

    object obj = method.Invoke(foo, new object[] { /* arguments here */ }); 
    // how can we cast obj to an IList<Type> - barType 
} 

Làm thế nào chúng ta có thể đúc kết quả của method.Invoke một IList của Loại từ lập luận barType?

Trả lời

5

Điểm của diễn viên thường là nói với trình biên dịch rằng bạn có thêm một số thông tin - bạn biết điều gì đó tại thời gian biên dịch. Bạn không biết thông tin đó ở đây - bạn chỉ biết thông tin đó tại thời gian thực hiện.

Bạn sẽ làm gì với giá trị sau khi truyền? Phải thừa nhận rằng có một số lần khi hữu ích - khi bạn phải sử dụng giao diện chung, ngay cả khi bạn muốn nhận được các thành viên không yêu cầu thông số loại (ví dụ: Count trong IList<T>). Tuy nhiên, nếu đó không phải là những gì bạn đang cố gắng để làm điều đó sẽ thực sự giúp đỡ nếu bạn có thể cung cấp thêm thông tin.

+0

Chúng tôi muốn lặp lại danh sách dưới dạng loại được truyền. Mà tôi thừa nhận không thực hiện bất kỳ ý nghĩa, chúng ta cần phải nói với trình biên dịch các loại để cho nó để tạo ra những gì nó cần. Mục tiêu của câu hỏi là để khám phá một trường hợp cạnh mà thực sự là một hack xung quanh một bất thường LOB. Cảm ơn bạn đã trình bày rõ ràng vấn đề cho tôi. – blu

0

Trong .NET 4.0 bạn có thể sử dụng cây biểu thức để đạt được điều đó.

0
private void LoadBars<T>() 
{ 
    Type barType = typeof(T); 
    // foo has a method that returns bars 
    Type foo = typeof(Foo); 

    MethodInfo method = foo.GetMethod("GetBars") 
     .MakeGenericMethod(bar); 

    IList<T> obj = (IList<T>)method.Invoke(foo, new object[] { /* arguments here */ }); 
} 
+1

Chính xác, nhưng bây giờ T phải được biết đến lúc biên dịch. – Radu094

0

Đúc sẽ chỉ có ý nghĩa nếu người gọi của chức năng của bạn mới barType tại thời gian biên dịch, và không phải là một runtime. Và một khi điều đó đúng, bạn chỉ có thể lấy mẫu chức năng cho:

private IList<T> LoadBars<T>() 
{ 
... 
return obj as IList<T>; 
} 
4

Tôi vừa kết thúc đấu vật với vấn đề này.
Đúng, bạn không thể đưa đối tượng vào một Ilist chung nhưng bạn có thể chuyển đổi nó thành một mảng được đánh mạnh mẽ bằng cách gọi phương thức "ToArray" của đối tượng List.

Giải pháp được lấy từ một blog khác. http://amazedsaint.blogspot.com/2008/04/creating-generic-list-at-runtime.html

ToArrayMethod = obj.GetType(). GetMethod ("ToArray");

System.Array strongTypedArray = (System.Array) ToArrayMethod.Invoke (obj, null);

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