Почему делает IEnumerator <T>, наследовались IDisposable, в то время как неуниверсальный IEnumerator не делает?

71
задан sashoalm 29 July 2016 в 08:46
поделиться

5 ответов

В основном это был контроль. В C# 1.0, foreach никогда названный Dispose <глоток> 1 . С C# 1.2 (представленный в VS2003 - существует № 1.1, причудливо) foreach начал регистрироваться finally блок, реализовал ли итератор IDisposable - они должны были сделать это тот путь, потому что ретроспективно создание IEnumerator расширяется IDisposable, повредил бы общую реализацию IEnumerator. Если они решили, что для foreach полезно избавиться от итераторов во-первых, я уверен IEnumerator, расширился бы IDisposable.

, Когда C# 2.0 и.NET 2.0 вышли, однако, у них была новая возможность - новый интерфейс, новое наследование. Это имеет намного больше смысла иметь интерфейс, расширяются IDisposable так, чтобы Вам не была нужна регистрация времени выполнения наконец блок, и теперь компилятор знает, что, если итератор IEnumerator<T>, это может испустить безусловный вызов к [1 113].

РЕДАКТИРОВАНИЕ: для [1 114] невероятно полезно быть названным в конце повторения (однако, это заканчивается). Это означает, что итератор может держаться за ресурсы - который делает выполнимым для него, скажем, считать файл линию за линией. Блоки итератора генерируют Dispose реализации, которые удостоверяются, что любой finally блоки, относящиеся к "текущей точке выполнения" итератора, выполняются, когда это расположило - таким образом, можно записать нормальный код в итераторе, и очистка должна произойти соответственно.

<час>

<глоток> 1 Оглядывающийся назад на 1,0 спецификации, это было уже определено. Я еще не был в состоянии проверить этот более ранний оператор, который 1,0 реализации не назвали Dispose.

80
ответ дан Edward Brey 24 November 2019 в 13:07
поделиться

IEnumerable< T> не наследовал IDisposable. IEnumerator< T> действительно наследовал IDisposable однако, тогда как неуниверсальный IEnumerator не делает. Даже когда Вы используете foreach для неуниверсального IEnumerable (который возвращает IEnumerator), компилятор будет все еще генерировать чек для IDisposable, и вызов Располагают (), если перечислитель реализует интерфейс.

я предполагаю универсальный Enumerator< T> наследовался IDisposable, таким образом, не должно быть типа-выполнения-check—, это может просто идти вперед, и вызов Располагают (), который должен иметь лучшую производительность, так как это может быть, вероятно, быть оптимизированным далеко, если перечислитель имеет пустое, Располагают () метод.

5
ответ дан Mark Cidade 24 November 2019 в 13:07
поделиться

IEnumerable' наследовали IDisposing? Согласно отражателю.NET или MSDN. Вы уверены, что не путаете его с IEnumerator? Это использует IDisposing потому что это только для перечисления набора и не предназначенное для долговечности.

0
ответ дан Aaron Powell 24 November 2019 в 13:07
поделиться

Немного трудно, чтобы быть категоричным на этом, если Вам не удается получить ответ от AndersH самостоятельно или кого-то близко к нему.

Однако мое предположение - то, что это касается ключевого слова "урожая", которое было представлено в C# одновременно. При рассмотрении кода, сгенерированного компилятором, когда "возврат урожая x" будет использоваться, Вы будете видеть метод, обернутый в классе помощника, который реализует IEnumerator; наличие убывания IEnumerator от IDisposable гарантирует, что может вымыться, когда перечисление завершено.

0
ответ дан Mark Cidade 24 November 2019 в 13:07
поделиться

IIRC Все это о наличии IEnumerable<T> и IEnumerable является результатом IEnumerable шаблонный материал.Net's предшествования. Я подозреваю, что Ваш вопрос таким же образом.

-2
ответ дан BCS 24 November 2019 в 13:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: