当您在ref类上实现析构函数时,C ++ / CLI可以帮助您生成IDisposable
脚手架。此外,如果您没有实现析构函数,但是您的类具有实现IDisposable
的成员变量,那么IDisposable
将再次在您的类上自动实现。它比C#中处理IDisposable
的方式更有帮助,也更好。
在实现保留在msclr::com::ptr
(包含RCW的智能指针)的ref类时,我遇到了这种行为。
ref class Test /* : IDisposable added by the compiler */
{
msclr::com::ptr<IWhatever> _aComObject;
}
在我的特定情况中,我的类引用的COM对象没有“锁定”某些非托管资源,它实际上只占用了CLR无法看到的一些非托管内存。因此,我想通过不实现IDisposable
类来避免混淆我的ref类的用户。相反,我想通过使用GC API来增加适当的内存压力,让CLR知道COM对象的存在。
所以,问题是:有没有办法在一个没有实现析构函数的ref类上抑制IDisposable
的实现,但是却保留了一个IDisposable
成员变量?
NB:通常这样做是错误的,因为它会阻止类的用户确定地处理底层的COM对象,但考虑到特定的情况,暴露{{1}有可能混淆我的ref类的用户,因为没有必要处理有问题的ref类。
我想一个选项是在没有析构函数的情况下实现msclr :: com :: ptr的变体。
任何其他抑制自动添加IDisposable的方法都将受到赞赏。感谢。
将IDisposable
声明为msclr :: com :: ptr(_aComObject
)的句柄。然后,编译器不会将msclr::com::ptr<IWhatever>^
视为com ptr对象的“所有者”,并且在删除Test时不会将其公开。
答案 0 :(得分:1)
我不确定我同意避免IDispose实现的ratioanle - 但为什么不在你的类中存储IWhatever *。然后,编译器不应生成IDisposable实现。
如果您不想要析构函数行为,那么com :: ptr包装器会为您带来什么好处?你总是可以在堆栈上声明一个com :: ptr,并且如果你真的需要的话,可以在任何给定的方法中为它指定成员指针。
答案 1 :(得分:1)
我认为答案是将一个句柄保存到msclr :: com :: ptr而不是“按值”保存它(它仍然将它作为句柄“幕后”保留) ,除了C ++ CLI编译器将其视为一个值 - 删除所有者对象(Disposed)时“删除”它(调用Dispose)。)