我的理解是,如果在foreach循环中调用实现IDisposable
模式的对象,则它会自动处理,而无需在使用或调用Dispose
方法中明确使用它。我有以下代码
class Program
{
static void Main(string[] args)
{
using (Employee e = new Employee() { Name = "John" }) ;
{
}
foreach (var e in GetEmployees())
Console.WriteLine(e.Name);
}
static List<Employee> GetEmployees()
{
Employee emp = new Employee() { Name = "Peter" };
Employee emp2 = new Employee() { Name = "Smith" };
List<Employee> emps = new List<Employee>();
emps.Add(emp);
emps.Add(emp2);
return emps;
}
}
class Employee : IDisposable
{
public string Name { get; set; }
public void Dispose()
{
Console.WriteLine("disposing " + Name);
}
}
我没有看到Dispose
方法返回的对象调用GetEmployees
。这是否意味着我需要在foreach循环中调用Dispose
?
答案 0 :(得分:4)
foreach
不会调用Dispose
方法,只会调用using
。 using
指令只是一个糖:
try {
// Initialize
}
finally {
// Dispose
}
是的,你必须自己写Dispose
电话,如下:
foreach (var e in GetEmployees())
{
Console.WriteLine(e.Name);
e.Dispose();
}
或
foreach (var e in GetEmployees())
{
using (e)
{
Console.WriteLine(e.Name);
}
}
考虑来自MSDN的Dispose Pattern,以便更好地理解Disposing
在.NET中的工作方式:
简单用例:
public class DisposableResourceHolder : IDisposable {
private SafeHandle resource; // handle to a resource
public DisposableResourceHolder(){
this.resource = ... // allocates the resource
}
public void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing){
if (disposing){
if (resource!= null) resource.Dispose();
}
}
}
具有可终结类型的复杂用例:
public class ComplexResourceHolder : IDisposable {
private IntPtr buffer; // unmanaged memory buffer
private SafeHandle resource; // disposable handle to a resource
public ComplexResourceHolder(){
this.buffer = ... // allocates memory
this.resource = ... // allocates the resource
}
protected virtual void Dispose(bool disposing){
ReleaseBuffer(buffer); // release unmanaged memory
if (disposing){ // release other disposable objects
if (resource!= null) resource.Dispose();
}
}
~ ComplexResourceHolder(){
Dispose(false);
}
public void Dispose(){
Dispose(true);
GC.SuppressFinalize(this);
}
}
更新:正如在评论中指出的那样,我认为您正在混淆Garbage Collection
和Disposing
。 Disposing
用于释放应用程序中.NET Framework外部的非托管资源。 Garbage Collection
会自动完成,除非您完全理解为什么需要它,否则不要强迫它。
答案 1 :(得分:2)
您必须手动调用Dispose(),或使用using()
语句