C#/ CLI:如果在其中使用Dispose(),则不会调用析构函数

obr*_*end 5 c# c++ dispose destructor command-line-interface

我有一个名为"CTransferManaged"的C++/CLI类,带有实现的终结器和析构函数:

CTransferManaged::~CTransferManaged()
{
    this->!CTransferManaged();
}
CTransferManaged::!CTransferManaged()
{
    //Clean up resources... 
}
Run Code Online (Sandbox Code Playgroud)

这个类包含一个名为"CTransfer"的C#类包含一个CTransferManaged类型的对象m_transfer.

如果此类的析构函数只清除对象m_transfer的引用,我可以看到析构函数被调用(命中断点):

~CTransfer()
{
    m_transfer = null; //breakpoint on this line
}
Run Code Online (Sandbox Code Playgroud)

如果我调用m_transfer对象的Dispose()函数而不更改其他任何东西,则不再调用析构函数(断点不再命中).任何猜测为什么?

~CTransfer()
{
    m_transfer.Dispose(); //breakpoint on this line
    m_transfer = null;
}
Run Code Online (Sandbox Code Playgroud)

我想手动调用Dispose(),因为我发现如果我不手动调用Dispose,则不会正确清理C++/CLI对象(m_transfer)的资源.目前我不确切知道为什么.

为什么一旦调用CTransferManaged :: Dispose()(C++/CLI)就不再调用CTransfer(C#类)的析构函数?

S N*_*ash 0

C# 析构函数只能由垃圾收集器调用,不能直接调用。

Dispose 是 IDisposalbe 接口的一部分,只能手动调用,并且不会触发析构函数。

不要依赖析构函数,而是尝试实现 iDisposabe 并直接调用 Dispose 方法并将代码放在那里。

如果 Resource 类包含应处置的嵌入对象,则 C# 需要此模式:

// C#
public class Resource : IDisposable
{
   private EmbeddedResource embedded;

   public Resource()
   {
      Console.WriteLine("allocating resource");
      embedded = new EmbeddedResource();
   }

   ~Resource()
   {
      Dispose(false);
   }

   protected virtual void Dispose(bool disposing)
   {
      Console.WriteLine("release resource");
      if (disposing)
      {
         embedded.Dispose();
      }
   }

   public void Dispose()
   {
      Dispose(true);
   }
}
Run Code Online (Sandbox Code Playgroud)