实施 IDisposable C#

Implementing IDisposable C#

我在理解 IDisposable 接口时遇到了一些问题

我正在开发一个游戏引擎并对我的解决方案进行 运行 代码分析,并被告知在我的 "GrapicsEngine" class 上实现 IDisposable 接口,因为它包含一个位图实例.

当然,我在互联网上搜索以了解如何正确执行此操作并得出以下代码:

这是我的 class 成员:

private const int BITMAP_WIDTH = 4096;
private const int BITMAP_HEIGHT = 4096;

private Graphics backBuffer;
private Bitmap bitmap;

private Color clearColor;

private WindowSurface surface;

private GraphicsQuality quality;

private Viewport viewport;

这是我的 IDispoable 区域:

#region IDisposable

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if (disposing == true)
        ReleaseManagedResources();

    ReleaseUnmanagedResources();
}

private void ReleaseManagedResources()
{
    if (bitmap != null)
        bitmap.Dispose();
    if (backBuffer != null)
        backBuffer.Dispose();
}

private void ReleaseUnmanagedResources()
{

}

~GraphicsEngine()
{
    Dispose(false);
}

#endregion

请注意,WindowSurface 是一个 WinForm 面板,GraphicsQuality 是一个枚举,Viewport 仅包含 int 值。

所以我有几个问题:

  1. 我是否正确地处理了我的资源?
  2. 我应该在非托管资源方法中处理哪些资源
  3. 如果我创建一个新的 class 并且它包含我的 GraphicsEngine class,那么 class 是否也应该实现 IDisposable?

如能提供有关此主题的任何帮助,我们将不胜感激。

你走在正确的轨道上。任何时候你有一个 class 级别变量是一次性的,包含的 class 也应该是一次性的。据我所知,你正在妥善处理它。我没有看到 class 名称行,所以我无法判断您是否包含 IDisposable 接口,但我想您已经实现了这些方法。如果不确定,请确保添加它。
IDisposable 是一种连锁反应类型的实现。如果变量是一次性的,并且它只是方法调用的本地变量,那么您可以在调用结束时处理它,但是如果它处于 class 级别,您可以实现 IDisposable 并使用 [=29= 处理它] 就像你在做的那样。这样任何使用您的 class 的人都可以妥善处理它。

例如:假设我在 class...

中打开了一个文件
public class MyClass
{
     private File txtFile = File.Create(...)
}

现在有人用我的class。

private void useClass()
{
     var myClass = new MyClass();
}

嗯,他们刚刚打开了一个文件,但没有妥善处理。

修改代码就可以这样使用了...

public sealed class MyClass : IDisposable
{
     private File txtFile = new File.Create(...)

     public void Dispose()
     {
          txtFile.Dispose();
          GC.SuppressFinalize(this);
     }

     ~MyClass() => Dispose();
}

当他们使用它时,他们可以像这样使用它...

private void useClass()
{
     using (var myClass = new MyClass())
     {
         //some code
     }
}

希望这能回答您的问题。请记住,如果您声明了一个局部于方法的一次性对象,那么您不必在 class 中实现 IDisposable,因为您将在该方法中处理它。但是,如果您在 class 级别范围内实现它,无论您是否有处理它的方法,您都应该实现 IDisposable 并检查以确保它在包含 class 调用处理时被处理。说得通? 希望这有帮助。