Список кастингов <MyObject>в IEnumerable <MyInterface> - PullRequest
2 голосов
/ 12 января 2010

Я все еще изучаю некоторые из этих вещей на C #, и я не смог найти ответ на этот вопрос. Предполагая, что у меня есть список MyObject, реализующий MyInterface

public class MyObject : IMyInterface { ...}

public List<MyObject> MyObjectList;

Как я могу вернуть IEnumerable<IMyInterface> с содержимым MyObjectList?

Я имею в виду, сейчас у меня есть это:

List<IMyInterface> temp = new List<IMyInterface>();
foreach (MyObject obj in MyObjects) temp.Add(obj);
return (IEnumerable<IMyInterface>)temp;

Но нужно ли создавать новый список, подобный этому?

Спасибо.

Ответы [ 3 ]

6 голосов
/ 12 января 2010

Если вы используете .NET 3.5, самый простой способ сделать это:

return MyObjects.Cast<IMyInterface>();

Вам не нужно создавать копию всего - но до тех пор, пока C # 4 не выйдет со своим универсальнымДисперсия интерфейса, вы застряли, делая что-то , как это.

Если вы все еще используете .NET 2.0, вы можете легко сделать что-то подобное:

public static IEnumerable<TResult> SafeCast<TSource, TResult>
    (IEnumerable<TSource> source) where TResult : TSource
{
    foreach (TSource item in source)
    {
        yield return item;
    }
}

(Обратите внимание, что это не проверяет, что source равно нулю; чтобы сделать это правильно, вам понадобятся два метода из-за отложенного выполнения блоков итераторов.)

Затем используйте:

return SafeCast<MyObject, IMyInterface>(MyObjects);

Вы могли бы сделать ее более похожей на версию LINQ, например:

public static IEnumerable<T> SafeCast<T>(IEnumerable source)
{
    foreach (T item in source)
    {
        yield return item;
    }
}

return SafeCast<IMyInterface>(MyObjects);

Это обеспечивает безопасность во время компиляции - это не остановит вас от попыток конвертироватьList<string> в IEnumerable<Guid> например.

0 голосов
/ 12 января 2010

Если вы используете C # 3 и .NET 3.5 (или выше), вы можете использовать предложение LINQ, которое представил Джейк:

return MyObjectList.Cast<IMyInterface>();

(нет необходимости в AsEnumerable в данном конкретном случае)

Однако, если вы используете предыдущую версию (2.0 C # и .NET или выше), вы все равно можете использовать блок итератора:

foreach(MyObject obj in MyObjectList) yield return (IMyInterface)obj;
0 голосов
/ 12 января 2010

Использование метода LINQ Cast хорошо работает здесь, что-то вроде MyObjects.Cast ()

...