繁体   English   中英

C ++ / CLI编译器何时创建哪种配置模式?

[英]When does the C++/CLI compiler create which dispose pattern?

这听起来像是一个很奇怪的问题,但是在C ++ / CLI类扩展了实现IDisposable的C#类的情况下,编译器会为dispose方法生成不同的内容,具体取决于某些内容。

(如果您对处置模式的外观感兴趣,我建议您阅读本节本节 。后者也提供有关C ++ / CLI的信息。 是一篇明确讨论从实现IDisposable的C#类派生C ++ / CLI类的文章。 。)

通过显示生成的IL代码(用Reflector提取)可以最好地说明该问题。 版本1:

[HandleProcessCorruptedStateExceptions]
protected override void Dispose([MarshalAs(UnmanagedType.U1)] bool A_0)
{
    if (A_0)
    {
        try
        {
            this.~Foo();
        }
        finally
        {
            base.Dispose(true);
        }
    }
    else
    {
        try
        {
            this.!Foo();
        }
        finally
        {
            base.Dispose(false);
        }
    }
}

版本2:

[HandleProcessCorruptedStateExceptions]
protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool A_0)
{
    if (A_0)
    {
        try
        {
            this.~Foo();
        }
        finally
        {
            base.Dispose();
        }
    }
    else
    {
        try
        {
            this.!Foo();
        }
        finally
        {
            base.Finalize();
        }
    }
}

请注意,在第一个版本中,将调用基本方法Dispose(bool),而在第二个版本中,将调用Dispose()或Finalize()。 这两个都是由几乎相同的代码生成的。 在第二种情况下,在基类中定义Dispose(bool)时会省略关键字“ virtual”。

似乎编译器正在尝试确定是否正确使用了Dispose模式并生成适当的代码。

我的问题是我遇到了一个基类如下所示的情况:

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

  protected virtual void Dispose(bool disposing)
  {
    if (disposing)
    {
    }
  }

但是生成的代码是版本2。现在,基本Dispose()函数实际上在派生类上调用Dispose(true),而派生类又调用base.Dispose(),并且我的堆栈溢出。

那么,编译器何时生成代码的每个版本?

当基类具有名为Dispose(bool)的非私有虚拟方法时,将发生具有Dispose(true)调用的代码的版本1。

当基类没有Dispose(bool)方法时,将发生带有Dispose()的代码的版本2。

该代码的第3版看起来与基本类具有非虚拟Dispose(bool)方法时发生的第2版几乎相同。 唯一的区别是C ++ Dispose(bool)函数还具有new关键字。

通过执行以下操作,我可以使您的情况发生:

  1. 使一个IDisposable类实现IDisposable而不使用Dispose(bool)方法。
  2. 对C#和C ++库进行完整编译。
  3. 修改C#类以添加虚拟Dispose(bool)方法。
  4. 编译(但不要全部重建)。

在这种情况下,C#代码会正确生成,但是C ++代码不会将Dispose(bool)函数调整为应有的值

修复非常简单:全部重建将损坏的版本2代码转换为正确的版本1代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM