C# IDisposable.Dispose()是否自动调用?

C# IDisposable.Dispose()是否自动调用?,c#,.net,idisposable,C#,.net,Idisposable,可能重复: 我有一个类,它有一些非托管资源。我的类实现了IDisposable接口,并在Dispose()方法中释放非托管资源。我必须调用Dispose()方法吗,还是会自动调用它?垃圾收集器会调用它吗?Dispose()不会自动调用。如果有终结器,它将被自动调用。实现IDisposable为类的用户提供了一种提前释放资源的方法,而不是等待垃圾收集器 客户机的首选方法是使用using语句,该语句处理Dispose()的自动调用,即使存在异常 IDisposable的正确实现是: class M

可能重复:

我有一个类,它有一些非托管资源。我的类实现了
IDisposable
接口,并在
Dispose()
方法中释放非托管资源。我必须调用
Dispose()
方法吗,还是会自动调用它?垃圾收集器会调用它吗?

Dispose()
不会自动调用。如果有终结器,它将被自动调用。实现
IDisposable
为类的用户提供了一种提前释放资源的方法,而不是等待垃圾收集器

客户机的首选方法是使用
using
语句,该语句处理
Dispose()
的自动调用,即使存在异常

IDisposable
的正确实现是:

class MyClass : IDisposable
{
  private bool disposed = false;

  void Dispose() 
  { 
    Dispose(true); 
    GC.SuppressFinalize(this);
  }

  protected virtual void Dispose(bool disposing)
  {
    if(!disposed)
    {
      if(disposing)
      {
        // Manual release of managed resources.
      }
      // Release unmanaged resources.
      disposed = true;
    }
  }

  ~MyClass() { Dispose(false); }
}
如果类的用户调用
Dispose()
则直接进行清理。如果垃圾收集器捕获了对象,它将调用
Dispose(false)
进行清理。请注意,从终结器调用时(方法
~MyClass
),托管引用可能无效,因此只能释放非托管资源。

Dispose()
不会自动调用。如果有终结器,它将被自动调用。实现
IDisposable
为类的用户提供了一种提前释放资源的方法,而不是等待垃圾收集器

客户机的首选方法是使用
using
语句,该语句处理
Dispose()
的自动调用,即使存在异常

IDisposable
的正确实现是:

class MyClass : IDisposable
{
  private bool disposed = false;

  void Dispose() 
  { 
    Dispose(true); 
    GC.SuppressFinalize(this);
  }

  protected virtual void Dispose(bool disposing)
  {
    if(!disposed)
    {
      if(disposing)
      {
        // Manual release of managed resources.
      }
      // Release unmanaged resources.
      disposed = true;
    }
  }

  ~MyClass() { Dispose(false); }
}
如果类的用户调用
Dispose()
则直接进行清理。如果垃圾收集器捕获了对象,它将调用
Dispose(false)
进行清理。请注意,当从终结器调用时(
~MyClass
方法),托管引用可能无效,因此只能释放非托管资源。

您必须手动调用此方法,可能(假设“MyClass”实现了“IDisposable”)在类似

using(var myclass = new MyClass())
{
   // do something with myclass
}

// now 'myclass'is Disposed
C#8.0中,您可以编写以下语句:

using var myclass=new MyClass();
“myclass”将在作用域的末尾自动处理

使用
语句(与显式调用Dispose()相比)的优点是无论您如何退出此块,都会调用
Dispose()
:通过运行到末尾,遇到
return
语句或抛出异常。

您可能必须手动调用此方法(假设“MyClass”在如下构造中实现“IDisposable”)

using(var myclass = new MyClass())
{
   // do something with myclass
}

// now 'myclass'is Disposed
C#8.0中,您可以编写以下语句:

using var myclass=new MyClass();
“myclass”将在作用域的末尾自动处理


与显式调用Dispose()相比,
使用
语句的优点是无论您如何退出此块,都会调用
:通过运行到末尾、遇到
return
语句或引发异常。

如果您在
using
语句中实例化对象,则在代码退出
using
块时会为您调用Dispose()

using(var myObject = new MyDisposableObject())
{
  blah();
} // Dispose() is called here (or whenever the code exits the block)
如果您没有使用来使用,则由您(调用代码)通过显式调用dispose()来处理对象


此外,如果调用方不调用Dispose(),您(MyObject的实现者)可以添加对终结器的支持。详细信息。

如果您在
语句中使用
实例化对象,则当代码退出
使用
块时,将为您调用Dispose()

using(var myObject = new MyDisposableObject())
{
  blah();
} // Dispose() is called here (or whenever the code exits the block)
如果您没有使用来使用,则由您(调用代码)通过显式调用dispose()来处理对象


此外,如果调用方不调用Dispose(),您(MyObject的实现者)可以添加对终结器的支持。详细信息。

要确保正确地释放资源,您需要在析构函数(终结器)中实现
IDisposable
和调用
Dispose


为了确保正确地释放资源,您需要在析构函数(终结器)中实现
IDisposable
并调用
Dispose


最新添加:当引用超出范围时,不会立即调用该终结器,而是在GC访问它时“一段时间(可能:很长时间)”调用它。因此:不要依赖终结器进行清理听起来像是说如果存在终结器,会自动调用Dispose(即使终结器不调用Dispose方法)。但是显式终结器不会自动调用Dispose方法,除非您显式地将终结器编码为调用Dispose。延迟添加:当引用超出范围时,不会立即调用该终结器,而是“过一段时间(可能:很长时间)”“当GC处理它时。因此:不要依赖终结器进行清理听起来像是说,如果终结器存在,就会自动调用Dispose(即使终结器不调用Dispose方法)。但是显式终结器不会自动调用Dispose,除非您显式地将终结器编码为调用Dispose。为什么
m
前缀?@KyleDelaney几年前我曾给私有成员添加
m
前缀…现在我使用
前缀。
m
代表
成员
。为什么
m
代表
成员refix?@KyleDelaney几年前我曾给私人成员加前缀,
m
,现在我用前缀。
m
代表
member