我正在阅读另一个答案。这让我想知道,如果我使用using
语句,什么时候需要显式调用Dispose?
编辑:
只是为了证明自己不是完全无知,我问的原因是因为另一条线程上的某个人说了一些暗示必须手动调用Dispose的好理由...所以我想,为什么不问问呢?
我正在阅读另一个答案。这让我想知道,如果我使用using
语句,什么时候需要显式调用Dispose?
编辑:
只是为了证明自己不是完全无知,我问的原因是因为另一条线程上的某个人说了一些暗示必须手动调用Dispose的好理由...所以我想,为什么不问问呢?
不需要这样做。使用 using
语句会自动帮你完成。
根据 MSDN,以下示例代码:
using (Font font1 = new Font("Arial", 10.0f))
{
byte charset = font1.GdiCharSet;
}
当编译时,会将其扩展为以下代码(请注意额外的花括号以创建对象的有限作用域):
{
Font font1 = new Font("Arial", 10.0f);
try
{
byte charset = font1.GdiCharSet;
}
finally
{
if (font1 != null)
((IDisposable)font1).Dispose();
}
}
注意:正如@timvw提到的那样,如果你在using语句中链接方法或使用对象初始化器,并且抛出异常,则该对象将不会被处理。如果您查看它将扩展为什么,这是有道理的。例如:using(var cat = new Cat().AsDog())
{
// Pretend a cat is a dog
}
扩展为
{
var cat = new Cat().AsDog(); // Throws
try
{
// Never reached
}
finally
{
if (cat != null)
((IDisposable)cat).Dispose();
}
}
AsDog
显然会抛出异常,因为猫永远不可能像狗一样优秀。那么这只猫将永远不会被处理掉。当然,有些人可能会辩称猫不应该被处理掉,但那是另一个讨论...
无论如何,确保你在 using( 这里 )
中所做的是安全的,这样你就可以放心了。(显然,如果构造函数失败,对象就不会被创建,所以也不需要处理掉)。
通常情况下,不需要这么做。这就是使用using语句的目的。然而有一种情况你需要小心:
如果你将变量重新赋值给另一个值,则using语句只会对原始值调用Dispose方法。
using (someValue = new DisposableObject())
{
someValue = someOtherValue;
}
编译器甚至会对此发出警告:
可能是对本地变量 'someValue' 的错误赋值,该变量是 using 或 lock 语句的参数。Dispose 调用或解锁操作将在本地变量的原始值上执行。
使用c# 3.0的对象初始化时要小心。这里可以找到一个例子:http://ayende.com/Blog/archive/2009/01/15/avoid-object-initializers-amp-the-using-statement.aspx
using (var myDisposable = new MyDisposable())
{
...
}
基本上是由编译器翻译为
var myDisposable = new MyDisposable()
try
{
...
}
finally
{
myDisposable.Dispose();
}