嗨,如果我有以下情况,请澄清一下:
using (Object1) {
create Object2
}
// bookmark1
Object2 会与 Object1 一起在书签 1 处被销毁吗?Object2 属于 StringReader,Object1 属于 MemoryStream。
嗨,如果我有以下情况,请澄清一下:
using (Object1) {
create Object2
}
// bookmark1
Object2 会与 Object1 一起在书签 1 处被销毁吗?Object2 属于 StringReader,Object1 属于 MemoryStream。
两个对象都不会在块结束时被销毁。
Object1 将被Disposed,一个不同的概念;Object2 不会发生任何事情。
这两个对象都将被收集,并可能在稍后的某个时间完成。垃圾收集是不确定的——你不能依赖它何时发生。
有关更多信息,请参阅MSDN 上的IDisposable。
using 块实际上是这样的构造的语法糖:
try
{
Brush b = new SolidBrush(Color.Red);
}
finally
{
b.Dispose();
}
因此,'b' 将被放置在 try 块的末尾,除非发生超出应用程序控制的事情。
在块(bookmark1)的末尾,在您的示例中,只会处理对象 1。在文件流的情况下,这意味着流将被关闭并释放句柄,但实际的字符串对象仍将在内存中(准备好被 GC 清理)。在您的情况下, Object2 不会被释放,因此它使用的句柄仍将保持打开状态。最终,GC 将收集它,并调用它的终结器,此时它将被正确释放。
如果您希望两个对象都被正确“清理”,则它们都需要被处置,要么通过将它们包装在 using 语句中,要么手动调用 Dispose。
还有另一种可能更简洁的语法:
using (Object1 obj1 = new Object1(), Object2 obj2 = new Object2())
{
// Do something with obj1 & obj2
}
如果你这样做,obj1 和 obj2 都将在块的末尾被 Disposed。在您的情况下,这意味着两个对象都将关闭,并且它们的句柄将被释放。然后 GC 将在以后的垃圾收集中清理它们。
有关详细信息,请参阅MSDN 的使用页面。
object2不会与 object1 一起被销毁(处置)。但是,为 using 语句创建了一个单独的范围块,因此此时 object2 确实超出了范围。它的处置只是不确定的。
此外,如果 object2 也是 IDisposable 您可以这样做:
using (object1)
using (object2)
{
} // bookmark1
无论如何,正常的垃圾收集规则都适用:对象的托管资源(内存)仍以正常方式处理。使用/IDisposable 仅释放非托管资源。