Какие интерфейсы все массивы реализуют в C #? - PullRequest
68 голосов
/ 19 декабря 2010

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

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

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

Ответы [ 5 ]

69 голосов
/ 19 декабря 2010

Из документации (выделено мое):

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

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

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

public abstract class Array : ICloneable, IList, ICollection, IEnumerable, IStructuralComparable, IStructuralEquatable
63 голосов
/ 19 декабря 2010

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

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 (.NET Standard 1.0 и более поздних) есть два дополнительных интерфейса:

System.Collections.Generic.IReadOnlyList`1[System.Int32]
System.Collections.Generic.IReadOnlyCollection`1[System.Int32]
54 голосов
/ 04 августа 2013

Начиная с .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 , чтобы упомянуть эти два интерфейса.

1 голос
/ 23 января 2018

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

            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));

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

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

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

0 голосов
/ 03 апреля 2018

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

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

Ссылка

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

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