2010-01-04 31 views
11

si tengo Objecta que implementa ISomeInterfaceconvertir la lista de objetos a la lista de interfaces

por qué no puedo hacer esto:

List<objectA> list = (some list of objectAs . . .) 

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list); 

Por qué no puedo pegar en la lista en el constructor interfaceList? ¿Hay algún trabajo alrededor?

Respuesta

23

en C# 3.0 + Net 3.5 y hasta se puede solucionar este problema haciendo lo siguiente

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>()); 

la razón por la que esto no funciona es que el constructor para List<ISomeInterface> en este caso toma un IEnumerable<ISomeInterface>. Sin embargo, el tipo de la variable de lista solo es convertible a IEnumerable<objectA>. Aunque objectA puede ser convertible a ISomeInterface, el tipo IEnumerable<objectA> no es convertible a IEnumerable<ISomeInterface>.

Esto cambia en C# 4.0, lo que agrega compatibilidad Co y Contravariancia al lenguaje y permite dichas conversiones.

+1

@itowlson, esto es lo que el usuario está haciendo en la muestra. No especificaron que el comportamiento Agregar fuera parte de la solución deseada. – JaredPar

+1

Quiere decir .NET 3.5, no C# 3.5. –

1

Esto se trata en C# 4.0, no se puede hacer esto en C# 3.5 directamente. Sin embargo, puede crear una nueva lista a partir de esta lista y usar un operador de extensión o foreach para hacerlo limpiamente, aunque sea más lento que un lanzamiento al tipo que será provisto por covarianza contravariancia (siempre obtenga estos errores) en C# 4.

+1

ver mi comentario a Jared - No hay tal cosa como C# 3.5. –

+0

Arg, me recuerda al beauracrat en Futurama. Aunque dicho Linq ERA un cambio de idioma, y ​​no se introdujo hasta C# 3.5, entonces C# era 2.0 hasta que se le dieron las extensiones de linq, WCF era simplemente una actualización de framework en 3.0. – Spence

3

más fácil & más corto camino es:

var interfaceList = list.Cast<ISomeInterface>().ToList() 

O

List<ISomeInterface> interfaceList = list.Cast<ISomeInterface>().ToList() 

Tanto por encima de los códigos de muestra son iguales y se puede utilizar cada uno desea ...

+0

El lado derecho con el uso de ToList() es una buena idea. Pero tenga en cuenta que al usar var se oculta el tipo real de la variable y no es una buena práctica hacerlo. Lista interfaceList = list.Cast (). ToList(); así que fui a usar esta forma como la más clara, la versión más corta –

+0

@ KovácsEde, de acuerdo con el punto que usted mencionó, agregué el segundo formato de mi camino a esta respuesta, pero ambos son iguales. Cuando usamos 'var', de hecho estamos escribiendo nuestros códigos en un formato más corto y siempre podemos reconocer el tipo de la variable mirando el lado derecho de' = '. Por otro lado, incluso cuando usamos 'var', el compilador' C# 'es lo suficientemente claro como para reconocer el tipo real de la variable. Entonces, si desea una sintaxis más corta, use 'var' y reconozca el tipo de variable de los códigos en el lado derecho de' = 'else; puede usar el segundo formato. – RAM

Cuestiones relacionadas