Я вручную увеличиваю счетчик и передаю его функциям для обработки подмножеств данных. По возвращении из этих функций я обнаружил, что перечислитель не изменил состояние в родительской функции.
Вот упрощенная версия того, о чем я говорю.
class Program {
static void Main(string[] args) {
var input = new List<string>() {
"1",
"2",
"escape",
"3",
"4",
"return",
"5"
};
foreach(var line in ParseFile(input)) {
Console.WriteLine(line);
}
Console.ReadLine();
Environment.Exit(Environment.ExitCode);
}
private static IEnumerable<string> ParseFile(List<string> input) {
var enumerator = input.GetEnumerator();
while (enumerator.MoveNext()) {
if (enumerator.Current.Equals("escape")) {
foreach (var line in DoStuff(enumerator)) {
yield return line;
}
} else {
yield return enumerator.Current;
}
}
}
private static IEnumerable<string> DoStuff(IEnumerator<string> enumerator) {
do {
yield return enumerator.Current;
} while (enumerator.MoveNext() && (!enumerator.Current.Equals("return")));
}
}
Я вижу, что после выхода из DoStuff enumerator.Current по-прежнему ускользает и не увеличивается для возврата. Вот результаты с консоли:
1
2
побег
3
4
3
4
возвращение
5
Мой вопрос в том, что вызывает это? Передается ли во вторую функцию глубокая копия перечислителя? Если да, то почему это происходит? GetHashCode () одинаков для обоих объектов.
List<T>.Enumerator
- это структура, поэтому изменения функции происходят в копии. - person Lee   schedule 25.05.2017DoStuff(ref IEnumerator<string> enumerator)
) - person Evk   schedule 25.05.2017var enumerator = input.GetEnumerator();
возвращаетIEumerable<T>
(T
в данном случаеstring
), который также наследуетIDisposable
и, следовательно, должен быть правильноDispose()
, заключив его время жизни в операторusing
. - person Jesse C. Slicer   schedule 25.05.2017