2011-02-05 72 views
8

我想使用反射將項目添加到通用列表。在方法「DoSomething」,我想完成以下行,使用反射將項目添加到通用列表/集合

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

但我得到不同種類的錯誤。

下面是我完整的代碼

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(??????) 
      } 
     }  
    } 
} 

任何意見/建議?

+0

什麼類型是MyBaseCollection?它是否類似於名單?並非所有實現IEnumerable的類都保證有一個Add方法。 – JoeyRobichaud 2011-02-05 23:10:03

+0

@JoeRobich:MyBaseCollection是自己的收集實現,它是派生自IList ,即使答案爲列表應解決我的問題... – kayak 2011-02-05 23:14:49

回答

18

我想你想:

// 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 }); 

既然你不知道是什麼該集合的元素類型將會是(可能是Car,Bike,Cycle等),你會發現很難找到有用的演員。例如,雖然你說集合肯定是實現IList<SomeMyBaseClassSubType>,但這並不是那麼有用,因爲IList<T>不是協變的。當然,鑄造到IEnumerable<MyBaseClass>應該成功,但這不會幫助你,因爲它不支持突變。另一方面,如果您的集合類型實現了非通用類型IListICollection類型,則轉換爲這些類型可能會派上用場。

但是如果你確保該集合將實現IList<Car>(即你知道的元素集合的類型事先),事情更容易:

// 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

它解決了......, – kayak 2011-02-05 23:24:19

+0

添加項目到IList一定會解決,但在我的情況下,我需要輸入到IEnumerable bcos ..我有一個泛型類型的基類..「IList cln =(IList )pi.GetValue(this,null);」...所以你的第一個建議解決了...... 。(我轉換爲其他編碼要求的ienumerable) – kayak 2011-02-05 23:32:36

0

開始與typeof<List<>>.GetMethods,你不調用屬性的方法,但是屬性的類型的方法

0

你能不能避免反光一起並使用:

List<MyBaseClass> lstCar { get; set; } 

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

你也可以考慮使用一個接口或抽象方法...

4

作爲一種替代方案......只是不要;考慮非泛型IList接口:

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

雖然不是所有的泛型集合強制性來實現IList,他們幾乎都這樣做,因爲它支撐着這麼多的核心框架的代碼。