如何在迭代中断时释放实现 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
。
我有以下 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
。