I have a managed object in a c# dll that maintains an anonymous integer handle to an unmanaged object in a c++ dll. Inside the c++ dll, the anonymous integer is used in an s
The finalizer of any managed object should almost always be used only as a failsafe. As a general rule, if you have finalizer logic, then your object likely needs to implement IDisposable. The basic pattern for implementing IDisposable is (let's say the class name is MyClass):
public class MyClass : IDisposable
{
private int extHandle;
public MyClass()
{
extHandle = // get the handle
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(disposing)
{
// call dispose() on any managed objects you might have
}
// release the handle
}
~MyClass()
{
Dispose(false);
}
}
This also means that whatever code is creating and using this object needs to be able to manage the lifetime of the object. The easiest way is to enclose the instance in a using block, like this:
using(MyClass c = new MyClass())
{
// do things with c
}
The using block automatically calls Dispose on the object as it falls out of scope at the end of the block. Things, of course, get more complicated when the object needs to exist outside of a single function. In any case, whenever the object is finished with Dispose needs to be called.