什么时候需要一次性元素的 `using` 语句?

When do I need the `using` statement for Disposable elements?

我知道在下面的情况下,using 会释放一次性元素,即

using (StreamReader sr = StreamReader(filename)) 
{
    txt = sr.ReadToEnd();
}

但是,如果我在内联使用它,是否会出现同样的情况?如您所见,我没有将其定义为变量:

 txt = (StreamReader(filename)).ReadToEnd(); 

定义或不定义变量不会影响您是否需要处置对象。

如果创建了实现 IDisposable 的 class 的实例,您应该在完成后对其调用 Dispose

您可以使用 using 或手动调用 Dispose - using 语句通常更方便,更简单。

首先,dispose 方法的存在是为了让 class(在本例中为 System.IO.StreamReader)的开发人员释放他们可能持有的任何非托管资源(很多人使用它用于一般清理)。

通常,如果 class 实现了 IDisposable(因此包含 Dispose 方法),那么绝对应该调用它。

您在上面使用的 using 语句将编译成以下内容:

//Very roughly your code sample
using (var sr = new StreamReader())
{
    //Some code
}

//What gets spat out by the compiler
var sr = new StreamReader();
try
{
    //Some code
}
finally
{
    sr.Dispose();
}

如您所见,此模式意味着无论 //Some code 部分是否抛出 not 异常,都会调用 Dispose。

本质上,它是一个 C# 帮助程序,因此您不必编写上面的 safe 代码来确保处置一次性对象。

因为明显的好处,问题真的应该是"When shouldn't you use using"。

第二个示例中不会发生与第一个示例中相同的事情。在您的第二个示例中, StreamReader 将在该行执行后立即成为 eligible 进行垃圾收集,因为您没有将它存储在变量中(因此它会超出范围)。这里的关键词是 "eligible" - 无法保证对象何时会真正被清理。因此,第二行代码将导致文件锁定 "held",直到垃圾收集器开始对 StreamReader 进行垃圾收集。

另一方面,如果您在 StreamReader 上调用 Dispose(),它会立即释放对文件的锁定,而无需等待垃圾收集器。