Search code examples
c#c++-clidestructorraiifinalizer

C# dispose is not called when object leaves scope in C++/CLI


I have a C# object that is resposible for a ressource which looks like this:

  public sealed class CLoadingScope
  {
    private bool isDisposed;

    public CLoadingScope()
    {}

    ~CLoadingScope()
    {
      // must be disposed otherwise it is used incorrectly
      if (!isDisposed)
      {
        throw new ApplicationException("RAII object has not been disposed");
      }
    }

    public void Dispose()
    {
      // CLEANUP CODE HERE […]
      isDisposed = true;
      GC.SuppressFinalize(this);
    }
  };

I am using this in some C++/CLI code like this:

{
  CLoadingScope scope;
  // CODE THAT USES THE RESSOURCE HERE […]
}

But this results in the Exception being thrown. I was expecting this to work because Dispose is the destructor of C# classes and stack objects are destroyed at the end of their scope. At least that's how I interpreted the answer to this question. With all the naming and usage confusion of finalizers and destructors in C#, C++ and C++/CLI I assume I mixed up something. Can anybody tell me what? :)


Solution

  • If I understand correctly, you have authored this class in C#, and are using it from C++/CLI.

    You are correct that C++/CLI will automatically call Dispose for you--but that's only if the class you are dealing with implements IDisposable. In your case, your class does not implement IDisposable, and thus, Dispose in this case is just a normal method.

    Change your class as follows:

    public sealed class CLoadingScope : IDisposable