【问题标题】:What is Dispose when using IEnumerator? [duplicate]使用 IEnumerator 时的 Dispose 是什么? [复制]
【发布时间】:2019-10-01 19:14:23
【问题描述】:

我见过类似的问题,但答案似乎无法回答 IDispose 真正应该做的事情。

到目前为止,我有一个看起来像这样的类:

public class ArrayPointsEnumerator : IEnumerator<Vector3Int> {

    Vector3Int max;
    public ArrayPointsEnumerator(Vector3Int size) {
        max = size - Vector3Int.one;
    }

    Vector3Int point = Vector3Int.zero;
    public Vector3Int Current  => point;
    object IEnumerator.Current => point;


    public bool MoveNext() {

        // (same functionality as:) // // // // //
        // for(int x = 0; x < max.x + 1; x++)   //
        //  for(int y = 0; y < max.y + 1; y++)  //
        //   for(int z = 0; z < max.z + 1; z++) //

        if(point.z < max.z) point.z++;
        else {
            point.z = 0;
            if(point.y < max.y) point.y++;
            else {
                point.y = 0;
                if(point.x < max.x) point.x++;
                else return false;
            }
        }

        return true;

    }

    public void Reset() => point = Vector3Int.zero;

}

应该这样使用:

ClassWithArray {
    object[,,] array;
    Vector3Int Size => /*array.GetLength(0 through 2)*/;
    public ArrayPointsEnumerator ArrayPoints => ArrayPointsEnumerator(Size);
}

 ...

foreach(Vector3Int point in ClassWithArray.ArrayPoints {
    //do stuff
}

但它缺少 IDispose 方法,Visual Studio 为我提供了两个解决方案。


(这两个都是未经编辑的“快速修复”Visual Studio provies。)


实现接口。

public void Dispose() {
    throw new NotImplementedException();
}


使用 Dispose 模式实现接口。

private bool disposedValue = false; // To detect redundant calls

protected virtual void Dispose(bool disposing) {
    if(!disposedValue) {
        if(disposing) {
            // TODO: dispose managed state (managed objects).
        }

        // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
        // TODO: set large fields to null.

        disposedValue = true;
    }
}

// TODO: override a finalizer only if Dispose(bool disposing) above has code to free unmanaged resources.
// ~ArrayPointsEnumerator()
// {
//   // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
//   Dispose(false);
// }

// This code added to correctly implement the disposable pattern.
public void Dispose() {
    // Do not change this code. Put cleanup code in Dispose(bool disposing) above.
    Dispose(true);
    // TODO: uncomment the following line if the finalizer is overridden above.
    // GC.SuppressFinalize(this);
}



老实说,也许我在这里真的很愚蠢,但即使在查看了 Implementing a Dispose methodIDisposable Interface 的 Microsoft Docs 之后,我仍然对 Dispose() 应该做什么感到困惑。我也读过类似问题的答案,(也许我只是愚蠢或只是错过了一些东西)但他们似乎没有解释 Dispose() 是什么。

【问题讨论】:

  • 如果您查看IEnumerator&lt;T&gt; 的文档,您会看到一个示例实现,其中void Dispose() 的实现只不过是一个空方法,因为该实现没有任何需要明确发布的内容(就像你的代码一样)。
  • @NicklausBrain IEnumerator&lt;T&gt; 接口要求方法具有实现。 OP 正在询问该方法应该做什么,以便他可以提供实现。
  • 好的,所以真正的问题是什么是非托管资源以及如何(在您的 Dispose 实现中)释放它们?
  • @Igor ^ 是的,谢谢
  • 查看标记的重复项。短版:如果你实现了IEnumerator&lt;T&gt;,你也必须实现IDisposable,因为接口声明。但是没有要求您的IDisposable.Dispose() 方法实际上 任何事情。如果你没有任何东西要处理,那就不要处理任何东西。除此之外,我建议几乎不需要明确地实现IEnumerator&lt;T&gt;;编写一个迭代器方法,让编译器为您完成工作。您可以根据需要添加using,以确保在需要时处理资源。

标签: c#


【解决方案1】:

也许您只是因为代码中没有明显的 Dispose 内容而感到困惑?

Dispose 在这里释放非托管资源,例如(例如)外部数据连接、文件处理程序等。您似乎没有这些东西。

如果您的代码使用了实现自身 IDisposable 的东西,只需在其上调用 Dispose(使用所需的 try/catch/finally)

您也可以将某些字段设置为“null”,但它没有用或不推荐,GC 就是为了这个。

如果你不需要 Dispose 任何东西,就不要引入 IDisposable。如果它是由您无法删除的另一个接口引入的,只需将 Dispose() 的实现留空(带注释,以供将来参考)。

【讨论】:

    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 2019-03-25
    • 2020-12-18
    • 2010-10-11
    • 2016-05-23
    • 2011-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多