c#实现对象的idisable和dispose

本文关键字:dispose idisable 实现 对象 | 更新日期: 2023-09-27 18:10:27

假设我有如下内容:

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的变量为空,将设置原始对象(这是在两种情况下相同的对象)为空或只是局部变量引用它?我以前从来没有尝试过依赖注入,我想确保我不会把自己搞砸。

EDITED:所以问题是(在编辑之后)处理第二个和第三个对c有什么影响吗?

c#实现对象的idisable和dispose

如果我理解你的话,我觉得答案是"不"。为什么会因为另外两个引用被设置为空而将原始引用设置为空呢?然而,当"someemethod"退出时,"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
}

另一个注意事项—确保在IDisposable对象上调用Dispose—垃圾收集器不会为您这样做。一个简单的方法是使用using:

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

首先,IDisposable对你发布的代码没有影响,因为你没有调用Dispose,也没有任何using块。

其次,形参是按值传递的,所以当你把引用传递给MyFirstClassMySecondClassMyThirdClass的构造函数时,它们会得到一个引用的副本(不是底层对象的副本,这是一个重要的区别)。

因此,将c设置为nullMySecondClassMyThirdClass持有的引用没有影响。

但是,如果您在原始方法中处置对象的,那么(由于引用指向同一个对象)该对象也将在MySecondClassMyThirdClass中处置:
MyFirstClass c = new MyFirstClass();
MySecondClass second = new MySecondClass(c);
MyThirdClass third = new MyThirdClass(c);
c.Dispose();   // will also be disposed in MySecondClass and MyThirdClass

using(MyFirstClass c = new MyFirstClass())
{
    MySecondClass second = new MySecondClass(c);
    MyThirdClass third = new MyThirdClass(c);
}  // the object will also be disposed in MySecondClass and MyThirdClass