IEnumerator <t> .Current和IEnumerator.Current之间的关系以及为什么IEnumerator <t>实现了IDisposable </t> </t>

时间:2011-05-30 09:49:50

标签: .net generics collections

我正在实施ICollection&lt; T>并且在执行枚举器方面存在问题。

我理解IEnumerator&lt; T>必须实现IEnumerator的后兼容性(.NET 1.0)

但如果我正在实施IEnumerator&lt; T>,然后有2个当前属性。

我有两个问题:

  1. 他们的关系应该是什么?以下代码是否正确?

    T IEnumerator<T>.Current 
    { 
        get 
        {
            if (_cursor < 0 || _cursor >= _array.Length)
                throw new InvalidOperationException("Iterator position invalid");
            else 
                return _array[_cursor];
        } 
    }
    
    
    object IEnumerator.Current
    {
        get
        {
            return IEnumerator<T>.Current;
        }
    }
    
  2. 我收到此错误:非静态字段,方法或属性'System.Collections.Generic.IEnumerator.Current.get'

    需要对象引用

    (2)。为什么IEnumerator&lt; T>必须实现IDisposable。 Dispose用于非托管资源,但在一般情况下Enumerator会使用非托管资源吗?

2 个答案:

答案 0 :(得分:3)

有几种情况,IEnumerator<T>继承自IDisposable非常有用。

例如,取File.ReadLines()需要保持打开FileStream,这是一种非托管资源。

或者,如果您考虑使用yield syntax使用IDisposable的迭代器,则需要IEnumerator<int> MyIt() { try { yield return 1; } finally { //Do Something } } 才能使finally子句正常工作:

Current

通常,您可以像这样实施T Current//Implicit interface implementation { get { return something; } } object IEnumerator.Current{get{return Current;}}

((IEnumerator<T>)this).Current

由于您尝试在接口本身上获取静态属性,因此原始代码不起作用。您可能想要T Current{...}。但是如果你隐式实现{{1}},你根本不需要那个演员。

答案 1 :(得分:1)

  1. return ((IEnumerator<T>)this).Current;

  2. Dispose()用于告诉枚举器不再需要它(例如,您可以断开某些数据源,或者执行其他操作)。