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#.
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).
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.
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?
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.
I suppose one option would be to implement a variant of msclr::com::ptr without a destructor.
Any other method to suppress the automatic addition of IDisposable would be appreciated. Thanks.
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.
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)).
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With