I'm in the middle of converting some code from C++/CLI to C#. One of the objects has a destructor in the C++/CLI version. Some other C++/CLI code calls "delete" on this object after use.
Which method do I need to implement in the C# version of this object so those "delete"s continue to function the same (IDisposable.Dispose, the finalizer, or something else that I'm missing)?
I would say the IDisposable
interface is what you look for if you need deterministic disposal of resources. This is usually the case with unmanaged resources, such as unmanaged handles that need to be closed, streams or database connections.
In C++/CLI, if you declare a managed type (ref class
and the like), IDisposable
is implemented using the destructor syntax, and Dispose()
is called by using the delete
keyword. If you declare such an object of a managed type locally (without using the ^
operator or gcnew
), C++/CLI even automatically calls Dispose()
for you when the object goes out of scope. In that way, C++/CLI is more convenient than C#.
You won't be able to call delete
on the object when using C#, you'll need to call Dispose()
manually on it instead. Another way to dispose of IDisposable
objects is the using
block.
The finalizer (implemented in C# by using destructor syntax) is not the same as a C++ destructor, since it is not deterministic when it will be called. Objects with a finalizer are basically queued until the finalizer thread decides to call their finalizer, so effectively you never know exactly when that is called.
The best approach for dealing with unmanaged resources is probably a combination of the two. See here for the recommended approach:
http://msdn.microsoft.com/en-us/library/b1yfkh5e(v=vs.100).aspx
Note, however that when using IDisposable
, even though you can dispose of unmanaged resources deterministically, managed objects still need to be collected by the garbage collector (non-deterministically).
I just found an article explaining the differences of this between C++/CLI and C#. You might find it interesting:
http://weblogs.thinktecture.com/cnagel/2006/04/ccli-finalize-and-dispose.html
There's a terminology mismatch between C++/CLI and C#. The C++/CLI destructor (~Foo) is the IDisposable.Dispose() method implementation. A C++/CLI class doesn't explicitly implement IDisposable, it is automatic from just the presence of a destructor.
The C++/CLI finalizer (!Foo) is the C# destructor.
So the C++/CLI delete operator is equivalent to calling the Dispose() method. Beware of stack semantics in C++/CLI, triggered by a local variable of a reference type without the ^ hat. The compiler generates a hidden call to Dispose() at the end of the scope block. Which is equivalent to the C# using keyword. Hard to see from the source code so pay extra attention or look at the generated IL with ildasm.exe
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