处理所有实现 IDisposable 的嵌套对象

发布于 2024-12-11 19:17:26 字数 533 浏览 0 评论 0原文

我的项目中有以下代码。我是否必须显式处置内部类?如果是的话在哪里?

public class Outer : IDisposable
{
    Context context = new Context();
    Inner inner;

    public Outer()
    {
        inner = new Inner(context);
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

public class Inner : IDisposable
{
    Context context;

    public Inner(Context context)
    {
        this.context = context;
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

Context 类似于实体框架中的 DbContext。

I have the following code in my project. Do I have to dispose the inner class explicit? If so where?

public class Outer : IDisposable
{
    Context context = new Context();
    Inner inner;

    public Outer()
    {
        inner = new Inner(context);
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

public class Inner : IDisposable
{
    Context context;

    public Inner(Context context)
    {
        this.context = context;
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

Context is something like DbContext from Entity Framework.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

我是男神闪亮亮 2024-12-18 19:17:26

好吧,在这种情况下,您需要弄清楚什么应该真正“拥有”上下文。如果您在 Inner 中拥有它,那么您真的也需要在 Outer 中使用它吗?他们中谁真正对他们负责?在我看来,您确实想要:

public sealed class Outer : IDisposable
{
    private readonly Inner inner;

    public Outer()
    {
        inner = new Inner(new Context());
    }

    public void Dispose()
    {
        inner.Dispose();
    }
}

public sealed class Inner : IDisposable
{
    private readonly Context context;

    public Inner(Context context)
    {
        this.context = context;
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

请注意,将 OuterInner 密封后,无需编写受保护的 Dispose(bool dispose) method 等 - 这实际上是为了继承,这通常会变得很痛苦。如果您确实需要对OuterInner进行子类化,并且可能需要处置更多资源,那么您将需要更复杂的实现。

就我个人而言,如果可能的话,我尝试实现IDisposable,并且仅使用using语句将一次性的东西保留在局部变量中。当然这并不总是可行,但值得尝试......

Well, in this case you need to work out what should actually "own" the context. If you've got it in Inner, do you really need it in Outer as well? Which of them really takes responsibility for them? It looks to me like you really want:

public sealed class Outer : IDisposable
{
    private readonly Inner inner;

    public Outer()
    {
        inner = new Inner(new Context());
    }

    public void Dispose()
    {
        inner.Dispose();
    }
}

public sealed class Inner : IDisposable
{
    private readonly Context context;

    public Inner(Context context)
    {
        this.context = context;
    }

    public void Dispose()
    {
        context.Dispose();
    }
}

Note that having made both Outer and Inner sealed, there's no need to write a protected Dispose(bool disposing) method etc - that's really for inheritance, which becomes a pain in general. If you really need to subclass Outer and Inner with the possibility of needing to dispose more resources, you'll need a more complicated implementations.

Personally I try not to implement IDisposable if possible, and keep disposable things only within local variables with using statements. It's not always possible of course, but it's worth trying...

深居我梦 2024-12-18 19:17:26

是的,最好是 Dipsose inner,因为它实现了 IDisposable,而 Outer 拥有它。

在这个特定的设置中,它可以被证明是多余的这一事实并不重要。 Inner 稍后可能会在其他情况下使用,或者自行更改。您应该将您的实现与其隔离。

如果有的话,您可能会重新考虑 Inner 是否应该处理上下文。它不会创建它,而是将其传入。如果您可以消除 Inner.context 就更好了。

Yes, it is best to Dipsose inner, simply because it implements IDisposable and Outer owns it.

The fact that in this particular setup it can be shown to be superfluous is not important. Inner may later be used in another situation, or change itself. You should isolate you implementation from that.

If anything, you might reconsider if Inner should Dispose of the context. It doesn't create it but gets it passed in. Even better if you could eliminate Inner.context.

暮光沉寂 2024-12-18 19:17:26

在这种特定情况下,您不需要这样做,因为您已经处理了上下文。
但是,无论如何,您都应该丢弃它,以防 Inner.Dispose 发生变化。

一般来说,你应该宁可丢弃东西。
处理同一个物体两次不会造成问题。

In this specific case, you don't need to, since you're already disposing the context.
However, you should dispose it anyway, in case Inner.Dispose ever changes.

In general, you should err on the side of disposing things.
Disposing the same object twice won't cause problems.

拿命拼未来 2024-12-18 19:17:26

根据粘贴的代码,外部类应该处理上下文。如果您能够将分配和处置紧密结合在一起,那就太好了。上下文对象的生命周期可以由外部类非常合理地管理。

处理掉所有你能触及的物体是个坏主意。您应该只处理您自己分配的那些对象。

在内部类中进行处置还意味着在处置内部对象后您将无法使用外部对象。这在您发布的示例中很好,但一般情况下并非如此。

Based on the pasted code it's the Outer class which should Dispose of the context. It's great if you can keep allocation and disposing close together. The lifetime of the context object can be very sanely be managed by the Outer class.

It's a bad idea to dispose all the objects you can reach. You should only dispose those objects you allocated yourself.

Disposing in the Inner class can also mean you can't use the Outer object after you dispose the Inner object. This is fine in the sample you posted but not generally.

何时共饮酒 2024-12-18 19:17:26

是的,但您还应该正确实现 IDisposable。

  private bool _disposed;

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

  protected virtual void Dispose(bool disposing)
  {
     if (!_disposed)
     {
        if (disposing)
        {
           // Managed
           inner.Dispose();
        }

        // Unmanaged
     }

     _disposed = true;
  }

  ~Outer()
  {
     Dispose(false);
  } 

Yes, but you should also implement IDisposable correctly.

  private bool _disposed;

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

  protected virtual void Dispose(bool disposing)
  {
     if (!_disposed)
     {
        if (disposing)
        {
           // Managed
           inner.Dispose();
        }

        // Unmanaged
     }

     _disposed = true;
  }

  ~Outer()
  {
     Dispose(false);
  } 
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文