Andy Rich did spot a bug in my code and pointed to his related The long-awaited return of DF blog entry:

Reset() does not delete _win32FindData, so when Dispose is invoked on this class, it will not be deleted – only when the class is finalized.  That is, when Dispose is invoked, your finalizer is not called, but GC::SuppressFinalize(this) is.  You need to explicitly call !FilesEnumerator() from your destructor in order for it to be run when Disposing. 

An interesting difference between C++/CLI and C# - one that users familiar with C# may not be well aware of.

 

I had forgotten that behaviour so I fired .NET Reflector to verify and indeed:

 

public sealed override void Dispose()

{

      this.Dispose(true);

      GC.SuppressFinalize(this);

}

 

protected virtual void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1)

{

      if (flag1)

      {

            this.~FilesEnumerator();

      }

      else

      {

            try

            {

                  this.!FilesEnumerator();

            }

            finally

            {

                  base.Finalize();

            }

      }

}

 

protected override void Finalize()

{

      this.Dispose(false);

}

 

I will update the original blog entry to fix this. 

Thanks Andy!