C# Language 使用语句基础


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
        {
            // finally blocks are always run
            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();
    }
    // disposable.Dispose is called even if we return earlier
}

就像finally块一样,无论错误或返回,总是执行, using始终调用Dispose() ,即使出现错误:

int Foo()
{
    var fileName = "file.txt";

    using (var disposable = File.Open(fileName, FileMode.Open))
    {
        throw new InvalidOperationException();
    }
    // disposable.Dispose is called even if we throw an exception earlier
}

注意:由于无论代码流如何都可以保证调用Dispose ,因此最好确保Dispose在实现IDisposable时不会抛出异常。否则,新异常将覆盖实际异常,从而导致调试噩梦。

从使用块返回

using ( var disposable = new DisposableItem() )
{
    return disposable.SomeProperty;
}

由于try..finally的语义是using块转换的, return语句按预期工作 - 在执行finally块之前评估返回值并处理值。评估顺序如下:

  1. 评估try
  2. 评估并缓存返回的值
  3. 执行finally块
  4. 返回缓存的返回值

但是,您可能不会返回变量disposable本身,因为它将包含无效的,已处置的引用 - 请参阅相关示例