执行using块计数作为对其捕获的IDisposable的引用
本文关键字:IDisposable 引用 using 执行 | 更新日期: 2023-09-27 18:25:09
假设我已经定义了以下方法。
static object F()
{
return new object();
}
如果我编写如下代码,则返回的object
在作用域结束之前不能进行垃圾收集。
{
object x = F();
// cannot yet garbage collect the object
// returned by F (referenced as variable x)
}
// can now garbage collect the object
// returned by F (referenced as variable x)
如果我编写如下代码,那么返回的object
可以在F
返回后立即进行垃圾收集。
{
F();
// can now garbage collect the object
// returned by F
}
但现在假设我将F
的定义更改为以下内容。
static IDisposable F()
{
return new SomeDisposableObject();
}
如果我像下面这样编写代码,那么返回的对象将不会被垃圾收集,并且直到using
块结束才会被处理。
using (IDisposable x = F())
{
} // immediately x.Dispose()
// can now garbage collect the object
// returned by F
如果我像下面这样编写代码,行为是什么引用C#语言规范是一个优点。
using (F())
{
}
using
块是否算作对F
返回的实例的引用?
是。
你不能在没有参考的情况下处理一些东西。
规范规定using (expression) { statement }
被编译为:
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
resource
是一个参考。
作用域末尾没有对局部变量的隐式引用。一个实现可以(但不是必须)在您最后一次实际引用对象之后对其进行垃圾收集。换句话说,您的第二个代码块是不正确,因为允许在块结束之前收集x
。
{
object x = F();
// <-- x IS ALLOWED to be collected here
Thread.Sleep(5000);
// <-- The object x ref'd IS ALLOWED to be collected here, if it wasn't earlier
}
// <-- The object x ref'd IS ALLOWED to be collected here, if it wasn't earlier
使用块创建一个局部变量,以便在使用块结束时调用Dispose
。即使没有显式命名变量,引用也将一直有效,直到块结束。
using (F())
{
// The instance returned by F IS NOT allowed to be collected here
Thread.Sleep(5000);
// The instance returned by F IS NOT allowed to be collected here
}
// The instance returned by F IS allowed to be collected here