using是语法糖,可让您保证无需显式try-finally阻止即可清除资源。这意味着您的代码将更加整洁,并且不会泄漏非托管资源。
标准Dispose清除模式,用于实现该IDisposable接口的对象(FileStream。基类Stream在.NET中进行的操作):
int Foo()
{
var fileName = "file.txt";
{
FileStream disposable = null;
try
{
disposable = File.Open(fileName, FileMode.Open);
return disposable.ReadByte();
}
finally
{
// 最后块总是运行
if (disposable != null) disposable.Dispose();
}
}
}using通过隐藏显式来简化语法try-finally:
int Foo()
{
var fileName = "file.txt";
using (var disposable = File.Open(fileName, FileMode.Open))
{
return disposable.ReadByte();
}
//即使我们更早返回,也会调用Dispose
}就像finally块总是执行而不管错误或返回如何,using总是调用Dispose(),即使发生错误也是如此:
int Foo()
{
var fileName = "file.txt";
using (var disposable = File.Open(fileName, FileMode.Open))
{
throw new InvalidOperationException();
}
//即使我们提前抛出异常也会调用Dispose
}注意:由于Dispose可以确保无论代码流如何都调用它,因此最好在实现时确保Dispose不引发异常IDisposable。否则,实际异常将被新异常覆盖,从而导致调试恶梦。
using ( var disposable = new DisposableItem() )
{
return disposable.SomeProperty;
}由于try..finally该using块将其转换为语义,因此该return语句可以按预期工作-在finally执行块和处理该值之前先评估返回值。评估顺序如下:
评估try身体
评估并缓存返回的值
最后执行块
返回缓存的返回值
但是,您可能不会返回变量disposable本身,因为它将包含无效的,已处置的引用-请参见相关示例。