什么时候需要一次性元素的 `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()
,它会立即释放对文件的锁定,而无需等待垃圾收集器。
我知道在下面的情况下,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()
,它会立即释放对文件的锁定,而无需等待垃圾收集器。