[英]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
关键字。
通过执行以下操作,我可以使您的情况发生:
IDisposable
类实现IDisposable
而不使用Dispose(bool)
方法。 Dispose(bool)
方法。 在这种情况下,C#代码会正确生成,但是C ++代码不会将Dispose(bool)
函数调整为应有的值
修复非常简单:全部重建将损坏的版本2代码转换为正确的版本1代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.