I am trying to create a CLI C++ class that derives from HashAlgorithm
. HashAlgorithm
has a a virtual Dispose(bool)
method. I cannot override the Dispose
method because I get a compile error stating dispose
is a reserved keyword. From what I read online just adding a finalizer and dtor and the compiler will take care of everything else. I did this and the code compiles. When I try to use I get the error below:
System.TypeLoadException: Declaration referenced in a method implementation cannot be a final method
When I look at the code the compiler generated I see it puts this sealed keyword on the method which appears to be the source of the problem. The Dispose
method is not really needed at all because it already exists on the base class. Any idea on how to get around this.
public sealed override void Dispose()
As you noted, in C++/CLI we implement ~ClassName and !ClassName, and the C++/CLI compiler writes Dispose(void) and Dispose(bool) for us.
I tried deriving from HashAlgorithm, and I was able to get both the dispose & finalize to work. Perhaps there's a subtle difference in how you have some of the methods declared.
Here's my test code:
public ref class CppDispose : HashAlgorithm
{
private:
~CppDispose() { Debug::WriteLine("~CppDispose"); }
!CppDispose() { Debug::WriteLine("!CppDispose"); }
protected:
virtual void HashCore(array<Byte>^ aray, int ibStart, int cbSize) override { }
virtual array<Byte>^ HashFinal() override { return nullptr; }
public:
virtual void Initialize() override { }
};
int main(array<System::String ^> ^args)
{
{
CppDispose foo;
Debug::WriteLine("Disposing: ");
}
{
CppDispose^ foo = gcnew CppDispose();
Debug::WriteLine("Finalizing: ");
foo = nullptr;
GC::Collect();
}
return 0;
}
Output:
Disposing: ~CppDispose Finalizing: !CppDispose
So that you can see what's going on behind the scenes, here's the methods that the C++/CLI compiler wrote for us, decompiled to C# syntax. In this case, the parent class has Dispose(void) implemented, so it's not reimplemented here.
[HandleProcessCorruptedStateExceptions]
protected override void Dispose([MarshalAs(UnmanagedType.U1)] bool flag1)
{
if (flag1)
{
try
{
this.~CppDispose();
}
finally
{
base.Dispose(true);
}
}
else
{
try
{
this.!CppDispose();
}
finally
{
base.Dispose(false);
}
}
}
protected override void Finalize()
{
this.Dispose(false);
}