如何在迭代中断时释放实现 IEnumerable<T> 的泛型 class 中的资源?

how to free resources in generic class implementing IEnumerable<T> when iteration is interrupted?

我有以下 class,它包装了 class MyDatabase 的静态方法,即使迭代被中断,我也需要关闭 _cursor。

public class DbWrapper<T> : IEnumerable<T> where T : struct
{
    public static Dictionary<Type, int> _tablenumber = new Dictionary<Type, int>()
        {
           {  typeof(MyStruct), 100 }
           {  typeof(SomeStruct), 200 }
        };

    Cursor _cursor;

    public DbWrapper()
    {
        _cursor = MyDatabase.OpenCursorAll(_tablenumber[typeof(T)]);
    }

    IEnumerator<T> IEnumerable<T>.GetEnumerator()
    {
        T row;
        while (MyDatabase.Fetch<T>(_cursor, out row))
        {
            yield return row;
        }
        MyDatabase.CloseCursor(_cursor);
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        var me = this as IEnumerable<T>;
        return me.GetEnumerator();
    }
}

我可以通过在迭代之前使 class 实现 IDisposable 并在 using 块中创建 DbWrapper 实例来做到这一点。但是我想尽量减少调用代码。我也想知道直接在 foreach:

中调用构造函数是不是很好的风格
        foreach (var eRow in new DbWrapper<MyStruct>())
        {
            myList.Add(eRow.Name);
        }

或者我应该有 returns 实例的静态方法吗?

I would like to minimize the calling code

如果 Cursor 实现了 IDisposable,你就可以摆脱在构造函数中创建游标并将 yield 语句包装在 using 块中:

IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
    using(_cursor = MyDatabase.OpenCursorAll(_tablenumber[typeof(T)]))
    {
        T row;
        while (MyDatabase.Fetch<T>(_cursor, out row))
        {
            yield return row;
        }
        MyDatabase.CloseCursor(_cursor);
    }
}

请注意,即使未完全枚举枚举器,在使用 foreach 时也会自动调用 Dispose