2010-11-16 37 views
7

Tôi đã cố gắng thêm các mục vào IList thông qua phản ánh, nhưng trong khi gọi phương thức "Thêm", lỗi đã được gửi "đối tượng ref. Not set". Trong khi gỡ lỗi tôi đã biết rằng GetMethod ("Add") đã trả về một tham chiếu NULL.Thêm các mục vào Danh sách <T> bằng cách sử dụng phản chiếu

Type objTyp = typeof(MyObject); //HardCoded TypeName for demo purpose 
var IListRef = typeof (List<>); 
Type[] IListParam = {objTyp};   
object Result = IListRef.MakeGenericType(IListParam); 

MyObject objTemp = new MyObject(); 
Result.GetType().GetMethod("Add").Invoke(Result, new[] {objTemp }); 

Xin vui lòng trợ giúp.

+0

Tôi đã làm việc khá một chút với sự phản ánh một lúc trước, và tôi đi đến kết luận rằng tôi không thích sự quá tải của 'GetMethod (chuỗi)', bởi vì tôi không bao giờ biết nếu nó sẽ trở lại. Hãy thử sử dụng 'GetMethod (string, Type [])' hoặc 'GetMethod (string, BindingFlags)'. Có thể không làm cho nó hoạt động, và có thể chỉ là tôi nuôi ong hoang tưởng, nhưng tôi nhớ có rất nhiều sự nhầm lẫn về các vấn đề tương tự trước đây. – Alxandr

Trả lời

22

Bạn đang cố gắng tìm phương thức Add trong Type, không phải trong List<MyObject> - và sau đó bạn đang cố gắng gọi nó trên Type.

MakeGenericType trả về một loại, không phải là trường hợp thuộc loại đó. Nếu bạn muốn tạo một cá thể, Activator.CreateInstance thường là cách để đi. Hãy thử điều này:

Type objTyp = typeof(MyObject); //HardCoded TypeName for demo purpose 
var IListRef = typeof (List<>); 
Type[] IListParam = {objTyp};   
object Result = Activator.CreateInstance(IListRef.MakeGenericType(IListParam)); 

MyObject objTemp = new MyObject(); 
Result.GetType().GetMethod("Add").Invoke(Result, new[] {objTemp }); 

(Tôi cũng xin đề nghị bạn nên bắt đầu ước cho tên biến sau đây, nhưng đó là một vấn đề riêng biệt.)

+0

Cảm ơn bạn rất nhiều, bây giờ nó làm việc. Tôi bỏ lỡ gọi là "Activator.CreateInstance". – AbrahamJP

0

Bạn đã chỉ tạo ra một kiểu generic, bạn chưa tạo một thể hiện của loại. Bạn có một loại danh sách, nhưng bạn không có danh sách.

Result variabled chứa đối tượng Type, vì vậy Result.Gettype() trả về giống như typeof(Type). Bạn đang cố gắng tìm phương thức Add trong lớp Type, không phải là lớp danh sách của bạn.

thể bạn không sử dụng Generics thay vì phản chiếu, ví dụ .:

public static List<T> CreateListAndAddEmpty<T>() where T : new() { 
    List<T> list = new List<T>(); 
    list.Add(new T()); 
    return list; 
} 
+0

Giải pháp dựa trên Generics mà bạn đã đề xuất là một giải pháp thích hợp. Lý do tại sao tôi đã không đi cho generics là, phương pháp PropertyInfo.SetValue đã không chấp nhận tham khảo tham số chung khác tôi chắc chắn đã đi cho phiên bản Generics. – AbrahamJP

3
private static void Test() 
    { 
     IList<Guid> list = CreateList<Guid>(); 
     Guid objTemp = Guid.NewGuid(); 
     list.Add(objTemp); 
    } 

    private static List<TItem> CreateList<TItem>() 
    { 
     Type listType = GetGenericListType<TItem>(); 
     List<TItem> list = (List<TItem>)Activator.CreateInstance(listType); 
     return list; 
    } 

    private static Type GetGenericListType<TItem>() 
    { 
     Type objTyp = typeof(TItem); 
     var defaultListType = typeof(List<>); 
     Type[] itemTypes = { objTyp }; 
     Type listType = defaultListType.MakeGenericType(itemTypes); 
     return listType; 
    } 

IList.Add (object item); => bạn có thể sử dụng phương thức Add trong giao diện IList thay vì Reflection.

+0

Không hoạt động. 'IList Result = (IList) IListRef.MakeGenericType (IListParam);' ném 'InvalidCastException Không thể truyền đối tượng kiểu 'System.RuntimeType' để gõ 'System.Collections.IList'. ' –

+1

Có, bạn đúng Alex, cảm ơn cảnh báo của bạn. Tôi đã quên rằng tôi đã quên tạo cá thể. Và tôi chỉnh sửa mã, và trong thời gian này, nó được kiểm tra và nó đang hoạt động;))) – Doctor

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