2010-08-16 2 views
6

Я понимаю, что любая коллекция (здесь я говорю о регулярных не общих) должна была реализовывать ICollection, IEnumerable и IList для регулярной коллекции объектов или IDictionary в случае словарей.Почему мы реализуем интерфейсы рекурсивно?

[Тем не менее, вопрос, который я спрашиваю, не относится к коллекции]

IList является производным от ICollection и IEnumerable

ICollection является производным от IEnumerable

Разве это не просто достаточно, чтобы сделать коллекцию (Например, ArrayList) реализовать IList?

В обозревателе объектов показано, что классы коллекции (например, ArrayList) реализуют IList, ICollection и IEnumerator.

Я понимаю, что даже если мы укажем все три коллекции, .Net будет принимать определения только один раз.

Но мой вопрос,

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

  2. Или это просто свойство обозревателя объектов, которое отображает его как 3 отдельные реализации? [Только что проверили и обнаружили, что это не свойство обозревателя объектов. браузер объектов отображает только интерфейсы, которые указаны в определении класса]

+4

Указанные описания могут быть излишними, но они не являются рекурсивными. – dthorpe

ответ

1

Я считаю, что это просто должно быть понятным разработчикам или помочь обеспечить структуру интерфейса. Я имею в виду, представьте, что у вас есть интерфейс для классов структуры данных, и вы реализуете IDataObject. Затем IDataObject реализует ISecurable и ILoggable. Регулярные классы, которые вы создаете, могут просто реализовать IDataObject, но что, если создатель IDataObject позже изменит реализацию и лишит ILoggable? Это может изменить функциональность вашего кода. Поэтому, чтобы предотвратить это, когда вы создаете свой класс, который наследуется от IDataObject, вы можете прямо сказать, что вы хотите также реализовать ISecurable и ILoggable, чтобы быть в безопасности.

Я не знаю точно, почему они сделали это с IList, но эти две причины - это мое лучшее предположение о том, почему.

1

Для того, чтобы получить доступ к объекту через интерфейс, определение класса для объекта необходимо явно определить, что он реализует интерфейс ...

Например, я могу иметь следующее:

interface IAnimal { 
    public void Yelp(); 
} 

и следующий класс:

class Dog { 
    public void Yelp() { 
    // do yelping 
    } 
} 

Теперь собака действительно визжит; Однако, поскольку он не объявляет, что он реализует IAnimal, я не могу сделать следующее:

IAnimal poodle = new Dog(); 
poodle.Yelp(); 

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

class Dog : IAnimal { 
    public void Yelp() { 
    // do yelping 
    } 
} 
+0

Определение класса ИЛИ BASE CLASS должно указывать, что оно реализует интерфейс. Если Dog реализует IAnimal, а Poodle наследует от Dog, то пудель может быть передан в IAnimal и вызванную им функцию Yelp. – supercat

2

Не достаточно ли создать коллекцию (например ArrayList) для реализации IList?

Достаточно. Объявление класса:

public MyCollectionClass : IList { 
} 

Это будет означать ваше MyCollectionClass реализует IList, ICollection и IEnumerable.

В обозревателе объектов он отображает классы коллекции (например,ArrayList) реализуют IList, ICollection и IEnumerator.

Это либо деталь обозревателя объектов, либо базовый класс просто реализовал классы коллекции, указав все интерфейсы. Однако, действительно, нет никаких оснований для этого.

5

I считаю это просто браузер объектов, который отображает его таким образом. Я только попробовал:

using System.Collections; 
using System.Collections.Generic; 

public class Foo : IEnumerable<int>, IEnumerable 
{ 
    public IEnumerator<int> GetEnumerator() { return null; } 
    IEnumerator IEnumerable.GetEnumerator() { return null; } 

} 

public class Bar : IEnumerable<int> 
{ 
    public IEnumerator<int> GetEnumerator() { return null; } 
    IEnumerator IEnumerable.GetEnumerator() { return null; } 
} 

Загрузка этого объекта в обозревателе объектов показала оба интерфейса на обоих классах.

Обратите внимание, что иногда может точку для повторного объявления интерфейса, если вы унаследовав от другой реализации - это позволяет Переопредели интерфейс, если он ранее был реализован в явном виде или в не виртуально. Я не думаю, что это так, но стоит упомянуть.

В общем, вам определенно не нужно указывать все интерфейсы, и я бы вообще этого не делал.

+0

Это не работает для меня в VS2010. Кроме того, для моих пользовательских классов обозреватель объектов пропускает подразумеваемые интерфейсы. – ladenedge

+0

@ladenedge: Это было в VS2010 для меня тоже (VS2010 Pro, если это актуально). Он показывает мне интерфейсы в «Базовых типах». Что вы там показываете? –

+0

Привет, Благодарим за отзыв. Но это не свойство Object Browser. Я обнаружил, что когда-то вернулся. Если мы выводим его только из IList, браузер объектов показывает только IList. Если мы получаем как IList, так и IEnumerable, браузер объектов показывает оба. – SaravananArumugam

2

Теперь, я думаю, что вы просите, учитывая

interface IA {}; 
interface IB : IA {}; 
interface IC : IB {}; 

В чем разница между:

class MyClass : IC {}; 

и

class MyClass : IA, IB, IC {}; 

И ответ, абсолютно ничего. Вторая версия делает ее более понятной для других программистов, но либо будет генерировать идентичный код.

Смежные вопросы