using语句是否只处理它创建的第一个变量?
假设我有一个一次性对象MyDisposable
, MyDisposable
另一个一次性对象作为构造函数参数。
using(MyDisposable myDisposable= new MyDisposable(new AnotherDisposable())) { //whatever }
假设myDisposable
不会将AnotherDisposable
置于其dispose方法中。
这只能正确处理myDisposable
吗? 或者它也处理AnotherDisposable
?
using
是相当于
MyDisposable myDisposable = new MyDisposable(new AnotherDisposable()); try { //whatever } finally { if (myDisposable != null) myDisposable.Dispose(); }
因此,如果myDisposable
不调用AnotherDisposable
Dispose,则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)) { }
但是,还有不同的方法。 通常,当一个类采用一次性时,它本身将负责处理它所采取的对象。 例如,包装Stream
的StreamReader
将处理它包装的Stream
。 这意味着您选择的构造将起作用。 您可以在MyDisposable
实现相同的function,然后您采取的方法就可以了。
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块确保即使抛出exception,也会调用Dispose方法,1或代码提前退出块。
因此,对于使用单个块将仅确保将丢弃单个一次性对象。 另一方面,您可以使用嵌套的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
。 因此,只有using
语句创建的myDisposable
变量才会自动处理。