我可以阻止C ++ / CLI将IDisposable添加到我的ref类吗?

时间:2022-09-01 23:25:40

C++/CLI helpfully generates the IDisposable scaffolding for you when you implement a destructor on a ref class. Also, if you don't implement a destructor, but your class has a member variable which implements IDisposable, then IDisposable is again automatically implemented on your class. It's pretty helpful and much better than how IDisposable is handled in C#.

当您在ref类上实现析构函数时,C ++ / CLI可以帮助您生成IDisposable脚手架。此外,如果您没有实现析构函数,但是您的类具有实现IDisposable的成员变量,那么IDisposable将再次自动在您的类上实现。它比C#中处理IDisposable更有帮助,也更好。

I have run into this behaviour when implementing a ref class that holds onto an msclr::com::ptr (a smart pointer that contains an RCW).

在实现保存在msclr :: com :: ptr(包含RCW的智能指针)的ref类时,我遇到了这种行为。

ref class Test /* : IDisposable added by the compiler */
{
  msclr::com::ptr<IWhatever> _aComObject;
}

In my specific case, the COM object referenced by my class doesn't 'lock' some unmanaged resource, it effectively just uses up a bit of unmanaged memory that the CLR can't see. Therefore I would like to avoid confusing the users of my ref class by not implementing IDisposable the class. Instead I want to make the CLR aware of the existence of the COM object by using the GC API to add the appropriate memory pressure.

在我的特定情况下,我的类引用的COM对象不“锁定”某些非托管资源,它实际上只占用了CLR无法看到的一些非托管内存。因此,我想通过不实现IDisposable类来避免混淆我的ref类的用户。相反,我想通过使用GC API添加适当的内存压力使CLR知道COM对象的存在。

So, the question is: is there a way to suppress implementation of IDisposable on a ref class that doesn't implement a destructor, but does hold an IDisposable member variable?

所以,问题是:有没有办法在一个没有实现析构函数的ref类上抑制IDisposable的实现,但是它是否包含一个IDisposable成员变量?

NB: often this would be the wrong thing to do, as it would prevent users of the class from deterministically disposing of the underlying COM object, but given the particular circumstances, exposing IDisposable has the potential to confuse users of my ref class, since it really is not necessary to Dispose of the ref class in question.

注意:这通常是错误的做法,因为它会阻止类的用户确定地处理底层的COM对象,但考虑到特定的情况,暴露IDisposable有可能混淆我的ref类的用户,因为它真的没有必要处理有问题的ref类。

I suppose one option would be to implement a variant of msclr::com::ptr without a destructor.

我想一个选项是在没有析构函数的情况下实现msclr :: com :: ptr的变体。

Any other method to suppress the automatic addition of IDisposable would be appreciated. Thanks.

任何其他方法来抑制自动添加IDisposable将是值得赞赏的。谢谢。


Answer

Declare _aComObject as a handle to an msclr::com::ptr (msclr::com::ptr<IWhatever>^). The compiler does not then regard Test as being the 'owner' of the com ptr object, and does not Dispose it when Test is deleted.

声明_aComObject作为msclr :: com :: ptr的句柄(msclr :: com :: ptr ^)。然后编译器不会将Test视为com ptr对象的“所有者”,并且在删除Test时不会将其公开。

2 个解决方案

#1


I'm not sure I agree with the ratioanle for avoiding the IDispose implementation -- but why not just store an IWhatever* in your class. The compiler shouldn't then generate the IDisposable implementation.

我不确定我同意避免IDispose实现的ratioanle - 但为什么不在你的类中存储IWhatever *。然后,编译器不应生成IDisposable实现。

If you don't want the destructor behaviour then what benefit is the com::ptr wrapper buying you? You can always declare an com::ptr on the stack and assign your member pointer to it in any given method if you really need it.

如果您不想要析构函数行为那么com :: ptr包装器会为您带来什么好处?您总是可以在堆栈上声明一个com :: ptr,并在任何给定方法中为您指定成员指针,如果您真的需要它。

#2


I think the answer is to hold a handle to the msclr::com::ptr rather than holding it 'by value' (which is still holding it as a handle 'behind the scenes', except the C++CLI compiler treats it as a value - 'deleting' it (calling Dispose) when the owner object is deleted (Disposed)).

我认为答案是保持msclr :: com :: ptr的句柄而不是“按值”保持它(除了C ++ CLI编译器对待它之外,它仍然将它作为“幕后的句柄”保留)作为值 - 删除所有者对象(Disposed)时'删除'它(调用Dispose)。

#1


I'm not sure I agree with the ratioanle for avoiding the IDispose implementation -- but why not just store an IWhatever* in your class. The compiler shouldn't then generate the IDisposable implementation.

我不确定我同意避免IDispose实现的ratioanle - 但为什么不在你的类中存储IWhatever *。然后,编译器不应生成IDisposable实现。

If you don't want the destructor behaviour then what benefit is the com::ptr wrapper buying you? You can always declare an com::ptr on the stack and assign your member pointer to it in any given method if you really need it.

如果您不想要析构函数行为那么com :: ptr包装器会为您带来什么好处?您总是可以在堆栈上声明一个com :: ptr,并在任何给定方法中为您指定成员指针,如果您真的需要它。

#2


I think the answer is to hold a handle to the msclr::com::ptr rather than holding it 'by value' (which is still holding it as a handle 'behind the scenes', except the C++CLI compiler treats it as a value - 'deleting' it (calling Dispose) when the owner object is deleted (Disposed)).

我认为答案是保持msclr :: com :: ptr的句柄而不是“按值”保持它(除了C ++ CLI编译器对待它之外,它仍然将它作为“幕后的句柄”保留)作为值 - 删除所有者对象(Disposed)时'删除'它(调用Dispose)。