2011-02-05 37 views
8

Tôi muốn thêm một mục vào danh sách Chung bằng cách sử dụng phản chiếu. Trong phương pháp "DoSomething", tôi đang cố hoàn thành dòng sau,Thêm mục vào Danh sách chung/Bộ sưu tập bằng cách sử dụng phản chiếu

pi.PropertyType.GetMethod("Add").Invoke(??????) 

nhưng tôi nhận được các loại lỗi khác nhau.

Dưới đây là mã hoàn chỉnh của tôi

public class MyBaseClass 
{   
    public int VechicleId { get; set; }   
}  
public class Car:MyBaseClass 
{ 
    public string Make { get; set; } 
}  
public class Bike : MyBaseClass 
{ 
    public int CC { get; set; } 
}   
public class Main 
{ 
    public string AgencyName { get; set; } 
    public MyBaseCollection<Car> lstCar {get;set;} 

    public void DoSomething() 
    { 
     PropertyInfo[] p =this.GetType().GetProperties(); 
     foreach (PropertyInfo pi in p) 
     { 
      if (pi.PropertyType.Name.Contains("MyBaseCollection")) 
      { 
       //Cln contains List<Car> 
       IEnumerable<MyBaseClass> cln = pi.GetValue(this, null) as IEnumerable<MyBaseClass>; 

       **//Now using reflection i want to add a new car to my object this.MyBaseCollection** 
       pi.PropertyType.GetMethod("Add").Invoke(??????) 
      } 
     }  
    } 
} 

Bất kỳ ý tưởng/đề nghị?

+0

Loại nào là MyBaseCollection? Nó có giống với Danh sách không? Không phải tất cả các lớp thực hiện IEnumerable đều được đảm bảo có phương thức Thêm. – JoeyRobichaud

+0

@JoeRobich: MyBaseCollection là việc thực hiện bộ sưu tập của riêng nó bắt nguồn từ IList , Ngay cả câu trả lời cho Danh sách cũng sẽ giải quyết được vấn đề của tôi ... – kayak

Trả lời

18

Tôi nghĩ rằng bạn muốn:

// Cast to IEnumerable<MyBaseClass> isn't helping you, so why bother? 
object cln = pi.GetValue(this, null); 

// Create myBaseClassInstance. 
// (How will you do this though, if you don't know the element-type?) 
MyBaseClass myBaseClassInstance = ... 

// Invoke Add method on 'cln', passing 'myBaseClassInstance' as the only argument. 
pi.PropertyType.GetMethod("Add").Invoke(cln, new[] { myBaseClassInstance }); 

Vì bạn không biết những gì loại phần tử của bộ sưu tập sẽ là (có thể là Xe hơi, Xe đạp, Chu kỳ, v.v.) bạn sẽ thấy khó để tìm một dàn diễn viên hữu ích. Ví dụ: mặc dù bạn nói rằng bộ sưu tập sẽ là chắc chắn triển khai IList<SomeMyBaseClassSubType>, nhưng không phải tất cả đều hữu ích vì IList<T> không phải là biến thể. Tất nhiên, hãy đúc thành IEnumerable<MyBaseClass>nên thành công, nhưng điều đó sẽ không giúp bạn vì nó không hỗ trợ đột biến. Mặt khác, nếu loại bộ sưu tập của bạn đã triển khai các loại IList hoặc ICollection không chung chung, việc truyền tới những loại này có thể hữu ích.

Nhưng nếu bạn chắc chắn rằng bộ sưu tập sẽ thực hiện IList<Car> (tức là bạn biết các yếu tố kiểu của bộ sưu tập trước đó), mọi thứ dễ dàng hơn:

// A much more useful cast. 
IList<Car> cln = (IList<Car>)pi.GetValue(this, null); 

// Create car. 
Car car = ... 

// The cast helped! 
cln.Add(car); 
+0

Nó hoạt động ..., – kayak

+0

Thêm mục vào IList chắc chắn sẽ hoạt động nhưng trong trường hợp của tôi cần phải gõ cast để IEnumerable bcos .. tôi có một lớp cơ sở cho loại chung .. "IList cln = (IList ) pi.GetValue (điều này, null);" ... vì vậy đề nghị đầu tiên của bạn đã làm việc ... (Tôi đang chuyển đổi thành ienumerable cho các yêu cầu mã hóa khác) – kayak

+0

Ques: // (Làm thế nào bạn sẽ làm điều này mặc dù, nếu bạn không biết loại phần tử?) Trả lời: Tôi nhận được các giá trị từ vị trí khác nhau trong đối tượng hệ thống phân cấp ...., Không tạo ra lớp dẫn xuất tại thời gian chạy .. Trên mã là mẫu cho stackupflow prupose ..(thời gian thực nó phức tạp hơn.) – kayak

0

bắt đầu với typeof<List<>>.GetMethods, bạn không gọi một phương pháp của tài sản, nhưng một phương pháp của các loại tài sản

0

thể bạn chỉ cần tránh phản ánh tất cả cùng nhau và sử dụng:

List<MyBaseClass> lstCar { get; set; } 

lstCar.Add((MyBaseClass)new Car()); 

Bạn cũng có thể xem xét sử dụng một giao diện hoặc các phương pháp trừu tượng ...

+0

Tôi cần một số cách chung chung, Trên mã chỉ là mẫu..in thời gian thực tôi cần nó cho nhiều pruposes – kayak

+0

Bạn sẽ có thể khắc phục điều này với thừa kế, cá nhân tôi nghĩ rằng việc sử dụng sự phản ánh sẽ là không cần thiết nếu các lớp và các lớp con được cấu trúc chính xác. – Rob

4

Thay thế ... Chỉ cần không; xem xét các giao diện IList không chung chung:

IList list = (IList) {... get value ...} 
list.Add(newItem); 

Trong khi nó không phải là bắt buộc cho tất cả các bộ sưu tập chung để thực hiện IList, họ khá nhiều bài làm, vì nó củng cố như vậy rất nhiều mã khuôn khổ cốt lõi.

+0

Tôi đã đề cập đến điều này, nhưng tôi nghĩ rằng lớp thu thập của OP là của riêng mình. Trong trường hợp này, đó là nghi ngờ giao diện không chung chung đã được thực hiện. :) – Ani

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