假设我有一个一次性对象MyDisposable
,它将另一个一次性对象作为构造函数参数。
using(MyDisposable myDisposable= new MyDisposable(new AnotherDisposable()))
{
//whatever
}
假设myDisposable
不处置AnotherDisposable
内部它的处置方法。
这只会正确处理myDisposable
吗?还是它也处置AnotherDisposable
?
假设我有一个一次性对象MyDisposable
,它将另一个一次性对象作为构造函数参数。
using(MyDisposable myDisposable= new MyDisposable(new AnotherDisposable()))
{
//whatever
}
假设myDisposable
不处置AnotherDisposable
内部它的处置方法。
这只会正确处理myDisposable
吗?还是它也处置AnotherDisposable
?
using
相当于
MyDisposable myDisposable = new MyDisposable(new AnotherDisposable());
try
{
//whatever
}
finally
{
if (myDisposable != null)
myDisposable.Dispose();
}
因此,如果myDisposable
不调用 Dispose on AnotherDisposable
,using
也不会调用它。
为什么不嵌套它们?
using(var outer = new AnotherDisposable())
{
using(var inner = new MyDisposable(outer))
{
//whatever
}
}
现在至少你可以确定它们会被正确处理掉。
它不会“处置”任何东西。它调用其中Dispose
使用的对象的方法。清理其他任何东西是你的工作..也许通过调用另一个对象的 dispose 。
在这种情况下,它不会处理AnotherDisposable
. 有两种解决方案。
首先,您通常会执行以下操作:
using (AnotherDisposable anotherDisposable = new AnotherDisposable())
using (MyDisposable myDisposable= new MyDisposable(anotherDisposable))
{
}
但是,还有一条不同的路要走。通常,当一个类使用一次性对象时,它自己会处理它使用的对象。例如StreamReader
,包装 a 的Stream
将处置Stream
它包装的。这意味着您选择的构造将起作用。您可以在其中实现相同的功能,MyDisposable
然后您采用的方法就可以了。
C# 的 using 语句提供了一种语法快捷方式,用于使用 try/finally 块在实现 IDisposable 的对象上调用 Dispose。例如:
using (FileStream fs = new FileStream ("myFile.txt", FileMode.Open))
{
// ... Write to the file ...
}
编译器将其转换为: FileStream fs = new FileStream ("myFile.txt", FileMode.Open);
try
{
// ... Write to the file ...
}
finally
{
if (fs != null) ((IDisposable)fs).Dispose();
}
finally 块确保即使在抛出异常1 或代码提前退出该块时也会调用 Dispose 方法。
因此,使用单个块只会确保单个一次性对象将被丢弃。另一方面,您可以使用嵌套的 using 语句。喜欢
using (myDisposable d = new myDisposable())
{
using(Disposable2 d2 = new Disposable2())
{
// do something and dispose...
}
}
这将被转换为
try
{
// work around for myDisposable
try
{
// work around for Disposable2
}
finally
{
if (d2 != null)
((IDisposable)d2 ).Dispose();
}
}
finally
{
if (d!= null)
((IDisposable)d).Dispose();
}
using
您只在语句中初始化了一个一次性变量。AnotherDisposable
嵌套对象是通过正常初始化创建的,而不是通过using
. 因此,只有myDisposable
您使用该语句创建的变量using
才会被它自动处理。