.NET Почему в качестве параметра IEnumerable <string>можно передать строку []? - PullRequest
4 голосов
/ 31 марта 2009

Это действительный код:

void func(IEnumerable<string> strings){
    foreach(string s in strings){
        Console.WriteLine(s);
    }
}

string[] ss = new string[]{"asdf", "fdsa"};
func(ss);

Что я хочу знать, как неявное преобразование string[] -> IEnumerable<string> работает?

Ответы [ 5 ]

12 голосов
/ 31 марта 2009

из: MSDN Массив класса

В .NET Framework версии 2.0 класс Array реализует

  • IList<T>,
  • ICollection<T> и
  • IEnumerable<T>

универсальные интерфейсы. Реализации предоставляются массивам во время выполнения и поэтому не видны инструментам сборки документации. В результате универсальные интерфейсы не появляются в синтаксисе объявления для класса Array, и нет никаких справочных тем для элементов интерфейса, которые доступны только путем приведения массива к универсальному типу интерфейса (явные реализации интерфейса). Главное, что нужно знать при приведении массива к одному из этих интерфейсов, это то, что члены, которые добавляют, вставляют или удаляют элементы, выбрасывают NotSupportedException.

5 голосов
/ 31 марта 2009
Класс

Array, который является очень странным зверьком и обрабатывается очень специально компилятором и JIT (я думаю, подробнее об этом в книгах Рихтера и Дона Бокса), реализует IEnumerable<T>.

3 голосов
/ 31 марта 2009

Массивы реализуют IEnumerable, поэтому для любого T [] существует преобразование в IEnumerable .

2 голосов
/ 31 марта 2009

как работает строка неявного преобразования [] -> IEnumerable?

Этот тип упускает из виду то, что нет преобразования. Массивы реализуют (вы могли бы почти сказать «наследовать от», если это имеет больше смысла для вас) IEnumerable, и так string [] уже является IEnumerable & mdash; нечего конвертировать

0 голосов
/ 31 марта 2009

Это стандартное преобразование интерфейса; как требование, массивы (T[]) реализуют IEnumerable и IEnumerable<T>. Таким образом, string[] на 100% совместим с IEnumerable<T>. Реализация обеспечивается компилятором (массивы были в основном родовыми до того, как существовали дженерики .NET).

Из спецификации (ECMA 334 v4) - это следствие 13.1.4:

  • От одномерного массива типа S[] до System.Collections.Generic.IList<S> и основания интерфейсы этого интерфейса.
  • От одномерного массива типа S[] до System.Collections.Generic.IList<T> и базовых интерфейсов этого интерфейса, при условии неявного преобразования ссылок из S в T.

И помните, что IList<T> : IEnumerable<T>

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