Список кастингов <T>- проблема ковариации / контравариантности - PullRequest
14 голосов
/ 08 февраля 2011

Даны следующие типы:

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

Интересно, как я могу преобразовать List<MyClass> в List<IMyClass>? Мне не совсем понятны темы ковариации / контравариантности, но я понимаю, что из-за этого не могу просто составить список.

Я мог бы придумать только это тривиальное решение; не хватает элегантности, тратить ресурсы:

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

Как вы можете решить эту проблему более элегантно / качественно?

( Пожалуйста, имейте в виду, что мне нужно решение .NET 2.0, но для полноты картины я был бы рад увидеть более элегантные решения с использованием более новых версий фреймворка. )

Ответы [ 3 ]

21 голосов
/ 08 февраля 2011

Самый простой способ - это, вероятно, использовать ConvertAll:

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

Даже если вы используете .NET 2, вы можете использовать лямбда-синтаксис, если вы используете VS2008или выше.В противном случае всегда есть анонимные методы:

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

. В .NET 3.5 вы можете использовать LINQ с Cast, OfType или даже просто Select:

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

In.NET 4.0 вы можете использовать ToList напрямую без промежуточного приведения, из-за ковариации IEnumerable<T>:

var converted = original.ToList<IMyClass>();
1 голос
/ 08 февраля 2011

Это должен быть список?Решение IEnumerable может быть более эффективным:

 public IEnumerable<IMyClass> ConvertItems(List<MyClass> input)
 {
    foreach (var item in input)
    {
        yield return (IMyClass)item;
    }
 } 
0 голосов
/ 08 февраля 2011

(решение .NET 3.5)

List<MyClass> list = new List<MyClass> { ... };
List<IMyClass> converted = list.Cast<IMyClass>().ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...