Почему классы коллекций в C # (например, ArrayList) наследуются от нескольких интерфейсов, если один из этих интерфейсов наследуется от остальных? - PullRequest
31 голосов
/ 21 июня 2009

Когда я нажимаю клавишу f12 для ключевого слова ArrayList, чтобы перейти к метаданным, сгенерированным из vs2008, я обнаружил, что сгенерированное объявление класса выглядит следующим образом

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

Я знаю, что IList уже наследуется от ICollection и IEnumerable, так почему же ArrayList избыточно наследует от этих интерфейсов?

Ответы [ 6 ]

14 голосов
/ 21 июня 2009

ОК, я провел небольшое исследование. Если вы создаете следующую иерархию:

  public interface One
    {
        void DoIt();
    }

    public interface Two : One
    {
        void DoItMore();
    }

    public class Magic : Two
    { 
        public void DoItMore()
        {
            throw new NotImplementedException();
        }

        public void DoIt()
        {
            throw new NotImplementedException();
        }
    }

И скомпилируйте его, затем обратитесь к DLL в другом решении, введите Magic и нажмите F12, вы получите следующее:

 public class Magic : Two, One
    {
        public Magic();

        public void DoIt();
        public void DoItMore();
    }

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

Обновление: если вы откроете DLL в ILDASM, вы увидите следующее:

реализует ... Два

реализует ... Один.

3 голосов
/ 21 июня 2009

Дополнительные интерфейсы показаны, потому что они подразумеваются IList. Если вы внедряете IList, вы также должны реализовать ICollection и IEnumerable.

2 голосов
/ 21 июня 2009

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

1 голос
/ 21 июня 2009

С MSDN ....

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

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

0 голосов
/ 22 июля 2009

Я думаю, что CLR не поддерживает интерфейс, который наследуется от другого интерфейса.

C #, тем не менее, поддерживает эту конструкцию, но должен «сгладить» дерево наследования для совместимости с CLR.

[Изменить]

После получения рекомендаций снизу быстро настройте проект VB.Net:

Public Interface IOne
    Sub DoIt()
End Interface

Public Interface ITwo
    Inherits IOne
    Sub DoIt2()
End Interface

Public Class Class1
    Implements ITwo

    Public Sub DoIt() Implements IOne.DoIt
        Throw New NotImplementedException()
    End Sub

    Public Sub DoIt2() Implements ITwo.DoIt2
        Throw New NotImplementedException()
    End Sub
End Class

Компиляция результатов в следующем (C #):

public class Class1 : ITwo
{
    public Class1();
    public void DoIt();
    public void DoIt2();
}

Это показывает, что VB.Net НЕ выравнивает иерархию интерфейса в отличие от C #. Я понятия не имею, почему это так.

0 голосов
/ 21 июня 2009

Не принимайте это как ответ.

Я повторяю то, что workmad3 сказал выше.

Реализуя его в ArrayList, легко узнать, какие интерфейсы реализует ArrayList, а не переходить к IList и обнаруживать, что он реализует ICollection & IEnumerable.

Это избавляет от необходимости ходить туда-сюда по цепочке наследования.

РЕДАКТИРОВАТЬ: На базовом уровне интерфейс, реализующий другой интерфейс, не может обеспечить реализацию. Класс, производный (от IList), следовательно, косвенно также реализует ICollection и IEnumerable. Таким образом, даже если вы напишите свой собственный класс, реализующий IList (и не добавите ICollection, IEnumerable в объявлении), вы увидите, что ему придется предоставить реализацию для ICollection & IEnumerable.

И рассуждения workmad3 имеют смысл.

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