使用反射将项添加到通用列表/集合

kay*_*yak 8 c# generics reflection

我想使用反射将项添加到通用列表.在方法"DoSomething"中,我试图完成以下行,

pi.PropertyType.GetMethod("Add").Invoke(??????)
Run Code Online (Sandbox Code Playgroud)

但我得到了不同的错误.

以下是我的完整代码

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(??????)
            }
        }    
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么想法/建议吗?

Ani*_*Ani 19

我想你想要:

// 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 } );
Run Code Online (Sandbox Code Playgroud)

既然你不知道集合的元素类型是什么(可能是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);
Run Code Online (Sandbox Code Playgroud)


Mar*_*ell 5

作为替代...只是不要; 考虑非通用 IList 接口:

IList list = (IList) {... get value ...}
list.Add(newItem);
Run Code Online (Sandbox Code Playgroud)

虽然它不是强制性的所有泛型集合来实现IList,他们几乎都这样做,因为它支撑着这么多的核心框架的代码。