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有什么影响吗?
如果我理解你的话,我觉得答案是"不"。为什么会因为另外两个引用被设置为空而将原始引用设置为空呢?然而,当"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
块。
MyFirstClass
给MySecondClass
和MyThirdClass
的构造函数时,它们会得到一个引用的副本(不是底层对象的副本,这是一个重要的区别)。因此,将c
设置为null
对MySecondClass
和MyThirdClass
持有的引用没有影响。
MySecondClass
和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
或
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