В .NET Array расширяет только IEnumerable, поэтому будут ли происходить упаковки и распаковки, когда цикл foreach проходит через массив типов значений? - PullRequest
4 голосов
/ 15 апреля 2011

Массив расширяет только неуниверсальную версию IEnumerable, поэтому будут ли происходить упаковки и распаковки, когда цикл foreach проходит через массив типов значений?Если мое предположение верно, то как foreach проходит через массив типов значений?Разве он не использует метод Array.GetEnumerator?А если нет, то почему Array расширяет IEnumerable?

Спасибо

Ответы [ 2 ]

6 голосов
/ 15 апреля 2011

Array имеет много специальных оболочек во время выполнения.В частности, это псевдогенератор.т. е. если вы укажете конкретный тип массива, такой как T[], реализуйте универсальные интерфейсы коллекций, такие как IEnumerable<T>.

.конкретный тип со строго типизированным Current.Это работает, поскольку foreach не требует интерфейсов IEnumerator / IEnumerable, но работает и с правильно именованными элементами.

Таким образом, вы можете перебирать массивы с foreach без упаковки.

2 голосов
/ 26 декабря 2012

CodesInChaos ответ неверный.Массив типа значения повторяется без упаковки из-за специальной обработки в компиляторе C #, а не специальной обработки во время выполнения.Компилятор C # преобразует цикл foreach в цикл for, когда статический тип повторяющейся коллекции является типом массива.

Кроме того, ваш вопрос основан на неверном предположении («Массив расширяет только неуниверсальную версию»).IEnumerable ").Фактически, массивы реализуют универсальный IEnumerable<T>;просто это делается с использованием явной реализации члена по причинам обратной совместимости.(Кроме того, тот факт, что массивы реализуют универсальные интерфейсы , является случаем специальной обработки во время выполнения; вы не увидите их в определении System.Array при декомпиляции mscorlib.)

Это означает, что если у вас есть массив int[] a и вы вызываете a.GetEnumerator(), вы получите не универсальную ссылку IEnumerator.Тем не менее, вы можете явным образом привести, чтобы получить общую ссылку IEnumerator<int>: ((IEnumerable<int>)a).GetEnumerator().

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