假设我有以下内容:
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做任何事情吗?
答案 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
个阻止。
其次,参数按值传递,因此当您将引用传递给MyFirstClass
到MySecondClass
和MyThirdClass
的构造函数时,它们会获得副本引用(不是底层对象的副本,这是一个重要的区别)。
因此,将c
设置为null
不会影响MySecondClass
和MyThirdClass
所持有的引用。
但是,如果您在原始方法中处置对象,那么(因为引用指向同一个对象),该对象也将被置于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