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

StackOverflow https://stackoverflow.com/questions/1023375

Вопрос

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

public class ArrayList : IList, ICollection, IEnumerable, ICloneable

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

Это было полезно?

Решение

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

  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, вы увидите следующее:

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

реализует ... One.

Другие советы

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

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

Из MSDN ....

  

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

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

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

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

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

Это избавляет от необходимости возвращаться & amp; вперед цепочка наследования.

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

И аргументация workmad3 имеет смысл.

Я предполагаю, что 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#.Я понятия не имею, почему это произойдет.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top