Из того, что я прочитал, было принято решение о проектировании некоторых перечисляемых типов коллекций в качестве изменяемых структур вместо ссылочных типов по соображениям производительности.
Хороший вопрос.
Во-первых, вы правы. Хотя в общем случае изменяемые типы значений являются неприятным запахом кода, в данном случае они оправданы:
- Мутация почти полностью скрыта от пользователя.
- Маловероятно, что кто-либо будет использовать счетчик в замешательстве.
- Использование изменяемого типа значения действительно решает проблему реалистичной производительности в чрезвычайно распространенном сценарии.
Мне интересно, знает ли кто-нибудь, почему универсальный итератор Array был реализован как ссылочный тип, когда во многих других критических по производительности коллекциях вместо этого использовались изменяемые структуры.
Потому что, если вы относитесь к категории людей, которых беспокоит производительность перечисления массива, тогда почему вы вообще используете перечислитель? Это массив для Ради всего святого; просто напишите цикл for
, который перебирает свои индикаторы, как обычный человек, и никогда не выделяет перечислитель. (Или цикл foreach
; компилятор C # перезапишет цикл foreach
в эквивалентный цикл for
, если он знает, что коллекция циклов является массивом.)
Единственная причина, по которой вы сначала получите перечислитель из массива, это если вы передаете его методу, который принимает IEnumerator<T>
, в этом случае , если перечислитель является структурой, тогда вы в любом случае будешь заниматься боксом . Зачем брать на себя создание типа значения, а затем его упаковку? Просто сделайте его ссылочным типом.