Реализация интерфейса, который уже наследуется другим интерфейсом - PullRequest
6 голосов
/ 01 ноября 2008

Я часто вижу такие вещи:

interface A { ... }
interface B : A { ... }
class C : B, A { ...}

Почему вы указываете, что C реализует интерфейс A, когда B уже наследует A? Это имеет какое-то семантическое значение или это просто вопрос стиля?

(Одним из многих примеров является List<T>, реализующий IList<T> и ICollection<T>, тогда как IList<T> также происходит от ICollection<T>).


Обновление: Спасибо за подтверждение моего предположения, что это не имеет никакого смысла в семантике.

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

Если бы B был классом, C реализовал бы (повторно) элементы интерфейса только из A, если бы он назвал A явно после ':'.

[РЕДАКТИРОВАТЬ] Я изменил формулировку вопроса, чтобы избежать путаницы с явно реализованными элементами интерфейса, которые ограничивают использование элемента в случаях, когда объект приводится в качестве интерфейса.

1 Ответ

11 голосов
/ 01 ноября 2008

Я считаю, что это просто вопрос стиля. Это особенно важно, когда вы смотрите на классы фреймворка / библиотеки - например, в вашем примере подчеркивается идея, что этот класс можно рассматривать как ICollection или IList, при этом разработчику не нужно знать, что IList на самом деле является ICollection.

Не имеет функциональных последствий. В частности, этот код будет компилироваться независимо от того, класс 'C' явно реализует 'A':

namespace DotNetInterfaceTest {
    class Program {
        static void Main(string[] args) {
            A c = new C();
        }
    }

    interface A {
        void foo();
    }

    interface B : A {
        void bar();
    }

    class C : B {
        public void bar() {}
        public void foo() {}
    }
}
...