Casting List – problema de covarianza / contravarianza

Dado los siguientes tipos:

public interface IMyClass { } public class MyClass : IMyClass { } 

Me pregunto cómo puedo convertir una List en una List ? No estoy del todo claro sobre los temas de covarianza / contravarianza, pero entiendo que no puedo simplemente lanzar la Lista debido a eso.

Podría llegar a esta solución trivial solamente; careciendo de elegancia, desperdiciando recursos:

 ... public List ConvertItems(List input) { var result = new List(input.Count); foreach (var item in input) { result.Add(item); } return result; } .... 

¿Cómo puedes resolverlo de una manera más elegante / performante?

( Por favor, tenga en cuenta que necesito la solución .NET 2.0, pero para estar completo, me gustaría ver las soluciones más elegantes que usan versiones de framework más nuevas también ) .

La forma más simple es probablemente usar ConvertAll :

 List converted = original.ConvertAll(x => x); 

Incluso si usa .NET 2, puede usar la syntax lambda si usa VS2008 o superior. De lo contrario, siempre hay métodos anónimos:

 List converted = original.ConvertAll( delegate (MyClass x) { return x; }); 

En .NET 3.5 puede usar LINQ con Cast , OfType o simplemente Select :

 var converted = original.Cast().ToList(); var converted = original.OfType().ToList(); var converted = original.Select(x => (IMyClass) x).ToList(); 

En .NET 4.0 puede usar ToList directamente sin un molde intermedio, debido a la covarianza de IEnumerable :

 var converted = original.ToList(); 

¿Tiene que ser una lista? Una solución IEnumerable podría ser más eficiente:

  public IEnumerable ConvertItems(List input) { foreach (var item in input) { yield return (IMyClass)item; } } 

(Solución .NET 3.5)

 List list = new List { ... }; List converted = list.Cast().ToList();