Какие интерфейсы реализуют все массивы в C#?


как новый программист .NET 3.5, я начал изучать LINQ, и я нашел что-то довольно простое, что я не заметил раньше:

книга утверждает, что каждый массив реализует IEnumerable<T> (очевидно, в противном случае мы не могли бы использовать LINQ для объектов на массивах...). Когда я увидел это, я подумал про себя, что я никогда не думал об этом, и я спросил себя, что еще все массивы реализуют-поэтому я изучил System.Array С помощью обозревателя объектов (так как это базовый класс для каждого массива в среде CLR) и, к моему удивлению, он не выполняет IEnumerable<T>.

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

5 62

5 ответов:

С документация (выделено мной):

[...] класс Array реализует System.Collections.Generic.IList<T>,System.Collections.Generic.ICollection<T> и System.Collections.Generic.IEnumerable<T> универсальные интерфейсы. реализации предоставляются массивам во время выполнения и поэтому не видны инструментам построения документации.

EDIT: как указывает Jb Evain в своем комментарии, только векторы (одномерные массивы) реализуют общие интерфейсы. Относительно почему многомерные массивы не реализуют универсальные интерфейсы, я не совсем уверен, так как они реализуют не универсальные аналоги (см. объявление класса ниже).

The System.Array класса (т. е. array) также реализует эти неродовые интерфейсы:

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable

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

foreach (var type in (new int[0]).GetType().GetInterfaces())
    Console.WriteLine(type);

выполнение приведенного выше фрагмента приведет к следующему выводу (на .NET 4.0):

System.ICloneable
System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]

(`1 означает <T>)

начиная с .NET 4.5, массивы также реализуют интерфейсы System.Collections.Generic.IReadOnlyList<T> и System.Collections.Generic.IReadOnlyCollection<T>.

таким образом, при использовании .NET 4.5, полный список интерфейсов, реализованных массивами становится (полученный с помощью метода, представленного в ответ Хосама Али):

System.Collections.IList
System.Collections.ICollection
System.Collections.IEnumerable
System.Collections.IStructuralComparable
System.Collections.IStructuralEquatable
System.Collections.Generic.IList`1[System.Int32]
System.Collections.Generic.ICollection`1[System.Int32]
System.Collections.Generic.IEnumerable`1[System.Int32]
System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]

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

тщательно на интерфейсах массива, они могут реализовать их, но на самом деле они действительно не делают этого... Возьмите гагару на следующий код:

            var x = new int[] { 1, 2, 3, 4, 5 };
        var y = x as IList<int>;
        Console.WriteLine("The IList:" + string.Join(",", y));
        try
        {
            y.RemoveAt(1);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
        Console.WriteLine(string.Join(",", y));

он выдает следующий результат: результат

Итак, разбор работает, но не все поддерживается, что правильно с точки зрения коллекции фиксированной длины, но совершенно неправильно, если вы действительно считаете, что это список. Там идет Лисков принцип от твердого: (.

для быстрого тестирования этой поможет.

Я нашел реализацию IList<T>, ICollection<T>, IEnumerable<T> на SZArrayHelper вложенный класс массива.

но я должен предупредить вас - там вы найдете гораздо больше вопросов...

справка

после этого я получил только один-ther_is_no_array;)