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

时间:2011-10-26 18:24:30

标签: c# .net entity-framework

我的项目中有以下代码。我是否必须明确处理内部类?如果是这样的话?

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类似于Entity Framework中的DbContext。

5 个答案:

答案 0 :(得分:6)

那么,在这种情况下,您需要弄清楚应该“拥有”上下文的内容。如果你已经在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 disposing)方法等 - 这实际上是继承,这一般会变得很痛苦。如果确实需要子类OuterInner,可能需要处理更多资源,那么您将需要更复杂的实现。

我个人尝试来实现IDisposable,并且只使用using语句将一次性事物保存在局部变量中。当然,这并不总是可行,但值得尝试......

答案 1 :(得分:2)

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

在这个特定的设置中,它可以被证明是多余的这一事实并不重要。内部可能稍后在另一种情况下使用,或者自行改变。您应该将实现与此隔离开来。

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

答案 2 :(得分:0)

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

一般来说,你应该在处理事情方面犯错。
两次处理同一物体不会造成问题。

答案 3 :(得分:0)

是的,但你也应该正确实现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);
  } 

答案 4 :(得分:0)

基于粘贴的代码,它是应该处理上下文的外部类。如果你可以保持分配和紧密配置,那就太棒了。外部对象的生命周期可以由外层管理。

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

在Inner类中处置也意味着在处理Inner对象后不能使用Outer对象。在您发布的样本中这很好但通常不会。