Кастинг и наследование интерфейса - PullRequest
5 голосов
/ 15 января 2010

Каждый элемент имеет интерфейс, IItem. Кроме того, существует интерфейс, известный как IDrawableItem, который наследуется от Item.

Приведенный ниже код пытается нарисовать нарисованный элемент, но не может, поскольку коллекция, которую хранит этот класс, принимает только IItem Вы можете добавить все, что унаследовано от IItem к этому классу, но использование других методов может быть достигнуто только путем приведения.

foreach (var item in Items) {
    item.Draw();               // The casting would go here.
}

Я знаю, как разыграть, as и т. Д. ..., но приемлемо ли это? Это лучшая практика?

Просто интересно, есть ли другие способы справиться с такими сценариями.

Ответы [ 2 ]

11 голосов
/ 15 января 2010

Используйте Enumerable.OfType для извлечения только тех элементов Items, которые реализуют IDrawableItem:

foreach(var item in Items.OfType<IDrawableItem>()) {
    item.Draw();
}

Чтобы ответить на вопрос, заданный Nanook в комментариях, приведенный выше код, вероятно, будет переведен в код, эквивалентный следующему:

foreach(var item in Items) {
     if(item is IDrawableItem) {
        ((IDrawable)item).Draw();
     }
}

Конечно, действительно есть итератор за кулисами, который выглядит примерно так:

public static IEnumerable<T> OfType<T>(this IEnumerable<TSource> source) {
    if(source == null) {
        throw new ArgumentNullException("source");
    }
    foreach(TSource item in source) {
        if(item is T) {
            yield return (T)item;
        }
    }
}

Итак, это показывает, что мы, вероятно, повторяем только Items один раз. Конечно, не требуется, чтобы OfType был реализован, как указано выше, но это разумная вещь.

1 голос
/ 15 января 2010

Два альтернативных решения:

  • Храните предметы в отдельной коллекции.
  • Добавить DrawIfPossible() метод к IItem. IDrawableItem должен переопределить его для вызова Draw(), у других IItem() разработчиков должна быть пустая реализация.

Явные запросы типов считаются признаком того, что с дизайном что-то не так.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...