2015-03-20 3 views
5

Почему IList определяется как это?Почему IList <T> реализовать IEnumerable <T> и ICollection <T> в то время как ICollection <T> сам реализует IEnumerable <T>

public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable 

public interface ICollection<T> : IEnumerable<T>, IEnumerable 

public interface IEnumerable<T> : IEnumerable 

не Может быть просто

public interface IList<T> : ICollection<T> 

Таким образом, чтобы проверить, я создал эти интерфейсы, просто чтобы быть уверенным, что работает!

public interface IOne 
{ 
    string One(); 
} 

public interface ITwo : IOne 
{ 
    string Two(); 
} 

public interface IThree : ITwo, IOne 
{ 
    string Three(); 
} 

В то время как его совершенно нормально, Решарр жалуется на «избыточные интерфейсы».

Любые идеи, почему Microsoft продолжила эту реализацию?

+1

Где вы видели дублирование? (Каков ваш источник для источника 'IList ', так сказать?) –

+0

@JonSkeet: просто нажал 'F12' /' Перейти к определению' на 'IList '. Он показал мне «подпись метода» из «сборных метаданных». Просто посмотрел его оттуда. –

+1

Как в стороне, полезно использовать обратные ссылки для вещей, которые действительно являются кодом. (Я отредактировал дополнительные бит из вашего сообщения) –

ответ

9

Интерфейс «Наследование» является одним из самых вводящих в заблуждение терминов в разработке программного обеспечения. Вы не наследовали приседания, интерфейсы не имеют какой-либо реализации, поэтому вы также не можете наследовать ее. Вы только наследуете требование для реализации методов.

Добавление к этому требованию путем повторения декларации интерфейса ничего не меняет, у вас уже есть спрос и добавление дополнительного требования не имеет никакого значения. Поэтому, поскольку это не имеет значения, Microsoft очень просто повторяет интерфейс, поэтому вы можете одним махом сказать, какие интерфейсы реализованы, скажем, List. Вам не нужно переходить к объявлению интерфейса, чтобы увидеть, что List также реализует IEnumerable. Рекомендуется самоподписывающийся стиль кодирования.

Остерегайтесь другой стороны этой медали, два различных интерфейса с одним и тем же методом могут быть реализованы с помощью только одного метода . Хотя это часто полезно, иногда это не то, что вы хотите. Скажем, ICowboy и IPainter, оба они имеют метод Draw(). Он не должен делать то же самое :) Затем вам нужно вернуться к явной реализации, чтобы избежать двусмысленности.

Обращаясь к жалобе Resharper, это, конечно, не очень полезно. Resharper имеет тенденцию принимать худшее от программиста. Но если вы хотите закрыть его, вам нужно удалить IOne из списка наследования IThree, он избыточен. То же самое для класса, который реализует IThree, вам также необходимо удалить ITwo и IOne из списка наследования. Или просто отключите предупреждение.

+2

Хорошая точка => рекомендую самостоятельный документирующий стиль. –

+1

Спасибо @ Ханс.Кроме того, «Эрик Липперт» прекрасно объясняет это здесь: http: // blogs.msdn.com/b/ericlippert/archive/2011/04/04/so-many-interfaces.aspx # comments' –