2010-01-28 18 views
5

Suponga que tiene la siguiente clase:pasar una colección de interfaz

class Car : IPainting 
{ 
... 
} 

Entonces una función como esta:

void AddCars(IEnumerable<Car> collection) 

A continuación, un fragmento de código como este:

Car bmw = new Car(); 
Car mercedes = new Car(); 

IPainting a = (IPainting) bmw; 
IPainting b = (IPainting) mercedes; 

IPainting[] paintings = new IPainting[] {a, b}; 

AddCars(paintings); // fails to compile 

Este de Por supuesto, el curso no se compila porque el método AddCars() solo acepta una colección de Cars, pero de eso está hecho el conjunto de "pinturas".

Sé que C# 4.0 probablemente proporcionará una solución para esto. ¿Hay alguna solución para esto hoy?

Gracias,

Alberto

+1

C# 4.0, no nos proporcionará una solución para el código que tiene aquí. Nunca podrá pasar algo un tipo que sea más alto en la herencia hie rarchy a un método que espera algo más bajo. Como han señalado otros, su método debería tener en IPainting - no Auto para que esto funcione. –

Respuesta

3

C# 4 no permitirá que el código que ha escrito, ya que el método AddCars espera un IEnumerable<Car> que implementa IPainting. Esto no quiere decir que puede pasar cualquier clase que implemente IPainting (podría tener, por ejemplo, un class Bike : IPainting que no tiene nada que ver con la clase Car). Sin embargo, permitirá el revés, si tiene void AddCars(IEnumerable<IPainting> collection) puede pasar un List<Car> al método.

hasta entonces, tendrá que atenerse a pasar Car secuencias con el método, mediante el uso de algún mecanismo de fundición (como painting.Cast<Car>() sugirió en otras respuestas).

+0

¿Son las pinturas.Cast () de alguna manera más rápido que un bucle for que arroja cada objeto al tipo de coche? Gracias. – abenci

+0

@devdept: No puedo decir; nunca hizo comparaciones de rendimiento en eso. Sorprendería si no es lo suficientemente rápido para la mayoría de los escenarios del mundo real. –

4

Cómo sobre el uso de LINQ: AddCars(paintings.Cast<Car>());

+0

No usamos Linq. No usamos bases de datos en absoluto. ¿Dónde puedo leer más sobre el enfoque que sugirió? – abenci

+3

@devdept - eso es linq a los objetos, no linq a sql. No tiene nada que ver con las bases de datos. –

7

trate de usar un método genérico:

void AddCars<T>(IEnumerable<T> collection) where T : IPainting 
+0

¿Esta solución permitirá que las matrices Car [] y IPainting [] pasen a AddCars()? – abenci

+0

sí, permitiría eso. –

4

su código es fundamentalmente defectuoso. Su clase garantiza que todos los autos implementen IPainting, pero no hay garantía de que todos los IPainting sean automóviles.

Es probable que esto funcione con algo de fundición, pero creo que debería reconsiderar su diseño.

AddCars(new Car[] { bmw, mercedes }); 
+0

Tienes razón, pero sé que esto siempre es cierto. ¿Hay alguna forma de hacer cumplir esto? Con un solo objeto de Auto puedo lanzarlo fácilmente a IPainting, el problema es que no puedo hacer lo mismo para las colecciones. – abenci

Cuestiones relacionadas