Ответ 1
Нет, вам не нужно беспокоиться об этом.
Тот факт, что они возвращают реализацию IDisposable
, представляет собой деталь реализации - это потому, что блоки iterator в реализации Microsoft компилятора С# создают один тип, который реализует как IEnumerable<T>
, так и IEnumerator<T>
. Последний расширяет IDisposable
, поэтому вы его видите.
Пример кода для демонстрации этого:
using System;
using System.Collections.Generic;
public class Test
{
static void Main()
{
IEnumerable<int> foo = Foo();
Console.WriteLine(foo is IDisposable); // Prints True
}
static IEnumerable<int> Foo()
{
yield break;
}
}
Обратите внимание, что вам нужно обратить внимание на то, что IEnumerator<T>
реализует IDisposable
. Поэтому в любое время, когда вы итерации явным образом, вы должны распоряжаться им должным образом. Например, если вы хотите перебрать что-то и убедитесь, что вы всегда будете иметь значение, вы можете использовать что-то вроде:
using (var enumerator = enumerable.GetEnumerator())
{
if (!enumerator.MoveNext())
{
throw // some kind of exception;
}
var value = enumerator.Current;
while (enumerator.MoveNext())
{
// Do something with value and enumerator.Current
}
}
(А foreach
цикл сделает это автоматически, конечно.)