2012-02-19 6 views
7
interface IVehicle 
{ 
    void DoSth(); 
} 

class VW : IVehicle 
{ 
    public virtual void DoSth() { ... } 
} 

class Golf : VW { } 

class Lupo : VW 
{ 
    public override void DoSth() 
    { 
     base.DoSth(); 
     ... 
    } 
} 

en mi código tengo:es operador en la lista genérica

List<VW> myCars = new List<VW>(); 
myCars.Add(new Golf()); 
myCars.Add(new Lupo()); 

ahora quiero evaluar si tengo una lista de vehículos. algo como:

if(myCars is List<IVehicle>) 
{ 
    foreach(IVehicle v in myCars) 
     v.DoSth(); 
} 

¿cómo puedo hacer esto? el operador-is en la lista genérica no funciona. ¿Hay otra manera?

+0

Comprobación para ver si una lista de objetos 'VW' es una lista de objetos' IVehicle' parece tonto, ya que 'VW' hereda de' IVehicle' y, por lo tanto, estás escribiendo 'if (true)'. Además, dado que 'VW' hereda de' IVehicle' y 'myCars' es una' List ',' foreach (IVehicle v en myCars) 'simplemente funcionará. – Steven

+0

@Steven: una lista de VW es enfáticamente * no * una lista de IVehicle, porque puede agregar un Ford a una lista de IVehicle, pero no a una lista de VW. – phoog

+0

Sí, pero simplemente está iterando esa lista, lo cual es seguro. – Steven

Respuesta

11

Incluso con las reglas de varianza 4.0, una lista de VW no es siempre una lista de IVehicle, incluso si un VW es un vehículo de IVehicle. Esa no es la forma en que funciona la varianza.

Sin embargo, en 4.0, se puede utilizar:

var vehicles = myCars as IEnumerable<IVehicle>; 
if(vehicles != null) { 
    foreach(var vehicle in vehicles) {...} 
} 

Desde IEnumerable<out T> exposiciones covarianza.

+4

Y 'if (myCars is IEnumerable )' funcionará también en .NET 4.0. – Steven

+0

Para completar, debería tener en cuenta que ** arrays ** puede ser covariante (para tipos de referencia), pero en modo can-error-at-runtime. –

+2

@Steven de hecho; Odio hacer la prueba dos veces; p –

2

En .NET 4 es posible utilizar la varianza de parámetros genéricos. Lea más sobre esto here

0

Usted puede hacer esto:

if (typeof(IVehicle).IsAssignableFrom(myCars.GetType().GetGenericArguments[0])) 
    foreach (IVehicle v in myCars) 
     //... 

Esto supone que sabe myCars es un tipo genérico. Si no lo sabe con certeza, primero deberá hacer un control adicional o dos.

Sin embargo, puesto que no está utilizando cualquier miembro de la lista, que no GetEnumerator, usted puede hacer esto:

if (myCars is IEnumerable<IVehicle>) //... 
Cuestiones relacionadas