[英]Add item to Generic List / Collection using reflection
I want to add an item to a Generic list using reflection. 我想使用反射将项添加到通用列表。 In the method "DoSomething", I am trying to finish the following line,
在方法“DoSomething”中,我试图完成以下行,
pi.PropertyType.GetMethod("Add").Invoke(??????)
but I am getting different kinds of error. 但我得到了不同的错误。
Below is my complete code 以下是我的完整代码
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(??????)
}
}
}
}
Any ideas / suggestion ? 有什么想法/建议吗?
I think you want: 我想你想要:
// 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 } );
Since you don't know what the element-type of the collection is going to be (could be Car, Bike, Cycle etc.) you're going to find it hard to find a useful cast. 既然你不知道集合的元素类型是什么(可能是Car,Bike,Cycle等),你会发现很难找到有用的演员阵容。 For example, although you say the collection will definitely implement
IList<SomeMyBaseClassSubType>
, that isn't all that helpful since IList<T>
isn't covariant. 例如,虽然你说集合肯定会实现
IList<SomeMyBaseClassSubType>
,但由于IList<T>
不是协变的,所以这并不是很有用。 Of course, casting to IEnumerable<MyBaseClass>
should succeed, but that won't help you since it doesn't support mutations. 当然,转换为
IEnumerable<MyBaseClass>
应该会成功,但这不会对你有所帮助,因为它不支持突变。 On the other hand, if your collection-type implemented the non-generic IList
or ICollection
types, casting to those might come in handy. 另一方面,如果您的集合类型实现了非通用
IList
或ICollection
类型,那么转换为那些可能会派上用场。
But if you're sure that the collection will implement IList<Car>
(ie you know the element-type of the collection beforehand), things are easier: 但是如果你确定该集合将实现
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);
As an alternative... Just don't; 作为替代......只是不要; consider the non-generic IList interface:
考虑非通用的IList接口:
IList list = (IList) {... get value ...}
list.Add(newItem);
While it isn't obligatory for all generic collections to implement IList, they pretty much all do, since it underpins such a lot of core framework code. 虽然它不是强制性的,所有的泛型集合来实现IList,他们几乎都这样做,因为它支撑着这么多的核心框架的代码。
以typeof<List<>>.GetMethods
开头,你不要调用属性的方法,而是调用属性类型的方法
Could you just avoid reflection all together and use: 你能不能一起避免反思并使用:
List<MyBaseClass> lstCar { get; set; }
lstCar.Add((MyBaseClass)new Car());
You could also consider using an interface or abstract methods... 您还可以考虑使用接口或抽象方法......
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.