C#实现IDisposable和Disposing of Objects

时间:2014-06-26 15:06:51

标签: c# dependency-injection

假设我有以下内容:

public void SomeMethod()
{
     MyFirstClass c = new MyFirstClass();
     using(var second = new MySecondClass(c))
     {
          using(var third = new MyThirdClass(c))
          {
               //do some stuff with second and third
          }
     }         
}

   public MyFirstClass()
   {
         //do some construtor stuff
   }

public class MySecondClass
{
   public MySecondClass(MyFirstClass cls)
   {
        PrivateFirstClassVar = cls;
   }

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

   public virtual void Dispose(bool disposing)
   {
        if(_disposed) return;
        if(disposing)
        {
            PrivateFirstClassVar = null;
        }
        _disposed = true;
   }
}

public MyThirdClass(MyFirstClass cls)
{
     PrivateFirstClassVar = cls;
     //same dispose method as MySecondClass
}

如果所有三个都实现了IDisposable,并且我将MySecondClass和MyThirdClass中的变量设置为null,那么是否将原始对象(在两种情况下都是同一个对象)设置为null或只是局部变量引用它?我之前从未尝试过使用依赖注入,而且我想确保自己不会搞砸。

编辑:所以问题是(编辑后)会处理第二个和第三个对c做任何事情吗?

2 个答案:

答案 0 :(得分:1)

答案看起来像"没有"对我来说,如果我了解你。为什么将原始引用设置为null,因为另外两个引用设置为null?然而,当" SomeMethod"退出,然后" c"超出范围,应该有资格进行垃圾收集。

让我们来看看它:

public void SomeMethod()
{
     // first (local-scope) reference is "c":
     MyFirstClass c = new MyFirstClass();

     // two more references in "second" and "third":
     MySecondClass second = new MySecondClass(c);
     MyThirdClass third = new MyThirdClass(c);

     //do some stuff

     // the 2nd and 3rd references set to null
     second = third = null;

    // when "SomeMethod" exits, "c" will be out of scope -- no references to the object remain
}

另一个注意事项 - 确保在Dispose个对象上调用IDisposable - 垃圾收集器不会为您执行此操作。一种简单的方法是使用using

public void SomeMethod()
{
     using (MyFirstClass c = new MyFirstClass())
     {
         using (MySecondClass second = new MySecondClass(c))
         {
             using (MyThirdClass third = new MyThirdClass(c))
             {
                 //do some stuff
             }
         }
     }
}

答案 1 :(得分:1)

首先,IDisposable与您发布的代码无关,因为您没有调用Dispose且没有using个阻止。

其次,参数按值传递,因此当您将引用传递给MyFirstClassMySecondClassMyThirdClass的构造函数时,它们会获得副本引用(不是底层对象的副本,这是一个重要的区别)。

因此,将c设置为null不会影响MySecondClassMyThirdClass所持有的引用。

但是,如果您在原始方法中处置对象,那么(因为引用指向同一个对象),该对象也将被置于MySecondClass和{{ 1}}:

MyThirdClass

MyFirstClass c = new MyFirstClass();
MySecondClass second = new MySecondClass(c);
MyThirdClass third = new MyThirdClass(c);

c.Dispose();   // will also be disposed in MySecondClass and MyThirdClass