2011-02-05 8 views
8

Quiero agregar un elemento a una lista genérica utilizando la reflexión. En el método "HacerAlgo", que estoy tratando de terminar la siguiente línea,Agregar elemento a la lista genérica/colección usando la reflexión

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

pero yo estoy haciendo diferentes tipos de error.

A continuación se muestra el código completo

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

cualquier idea/sugerencia?

+0

¿Qué tipo es MyBaseCollection? ¿Es similar a una lista ? No se garantiza que todas las clases que implementan IEnumerable tengan un método Add. – JoeyRobichaud

+0

@JoeRobich: MyBaseCollection es una implementación de colección propia que deriva de IList , incluso la respuesta para la lista debería resolver mi problema ... – kayak

Respuesta

18

Creo que desee:

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

Ya que no sé qué el tipo de elemento de la colección va a ser (podría ser Coche, Bicicleta, Ciclo, etc.) le resultará difícil encontrar un elenco útil. Por ejemplo, aunque diga que la colección va a definitivamente implementar IList<SomeMyBaseClassSubType>, no es de mucha ayuda ya que IList<T> no es covariante. Por supuesto, el lanzamiento a IEnumerable<MyBaseClass>debe tener éxito en, pero eso no lo ayudará, ya que no admite mutaciones. Por otro lado, si su tipo de colección implementó los tipos no genéricos IList o ICollection, la conversión a esos podría ser útil.

Pero si está seguro de que la colección implementará IList<Car> (es decir, se conoce el tipo de elemento de la colección de antemano), las cosas son más fáciles:

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

Funcionó ..., – kayak

+0

Agregar elemento a IList definitivamente funcionará, pero en mi caso necesito escribir hechizo para IEnumerable bcos..i tengo una clase base para el tipo genérico .. "IList cln = (IList ) pi.GetValue (this, null);" ... así que su primera sugerencia funcionó ... . (me estoy convirtiendo en ienumerable para otros requisitos de codificación) – kayak

+0

Ques: // (¿Cómo harás esto, si no conoces el tipo de elemento?) Respuesta: Obtengo valores de diferentes lugares en el objeto hierarchy ...., No crea clase derivada en tiempo de ejecución ... El código anterior es muestra para stackoverflow prupose ..(en tiempo real es más complejo.) – kayak

0

comienzo con typeof<List<>>.GetMethods, no se debe invocar un método de la propiedad, pero un método del tipo de la propiedad

0

Podría simplemente evitar la reflexión todos juntos y utilizar:

List<MyBaseClass> lstCar { get; set; } 

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

también podría considerar el uso de una interfaz o métodos abstractos ...

+0

Necesito alguna forma genérica, el código anterior es solo muestra..en tiempo real lo necesito para muchos temas – kayak

+0

Debería poder superar esto con herencia, personalmente creo que el uso de la reflexión Sería innecesario si las clases y subclases estuvieran estructuradas correctamente. – Rob

4

Como alternativa ... Simplemente no; considerar la interfaz IList no genérica:

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

Si bien no es obligatorio para todas las colecciones genéricos para implementar IList, que prácticamente todas las tienen, ya que sustenta una gran cantidad de código marco básico tales.

+0

Mencioné esto, pero creo que la clase de colección de OP es suya. En este caso, es dudoso que se haya implementado la interfaz no genérica. :) – Ani

Cuestiones relacionadas