I've been trying all day long getting a valid overload for the System.Object.Finalizer()-method. I need to inject a finalizer (if there is not already one) into random classes. The method itself should work just fine - at least reflected it looks valid and I can't see any CIL issues/errors.
This is the code that creates the overloaded method:
destructor = new MethodDefinition("Finalize",
MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual |
MethodAttributes.ReuseSlot, module.Import(typeof (void)));
baseType.Methods.Add(destructor);
All solutions I found on the internet (which all are rather outdated obviously) only show that you have to set those attributes - nothing more.
This is the compiler-generated version:
.method family hidebysig virtual instance void Finalize() cil managed
{
.override object::Finalize
.maxstack 2
L_0000: nop
L_0001: nop
L_0002: ldarg.0
L_0003: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_0008: ldarg.0
L_0009: ldfld class [App]App.Instancing.InstanceId App.Lab.Wpf.MainWindow::_instance
L_000e: call bool [App]App.Spy::UnsetToken(class [mscorlib]System.Type, class [App]App.Instancing.InstanceId)
L_0013: pop
L_0014: leave.s L_001e
L_0016: ldarg.0
L_0017: call instance void [mscorlib]System.Object::Finalize()
L_001c: nop
L_001d: endfinally
L_001e: ret
.try L_0001 to L_0016 finally handler L_0016 to L_001e
}
The following CIL code is my generated code. The most obvious mistake and probably the reason why it does not work is the missing ".override". I can't figure out how I achieve this. I tried about everything possible and it just doesn't work.
.method family hidebysig virtual instance void Finalize() cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: call instance class [mscorlib]System.Type [mscorlib]System.Object::GetType()
L_0006: ldarg.0
L_0007: ldfld class [App]App.Instancing.InstanceId App.Lab.Forms.MainWindow::vbbgsMtrInsVr0221
L_000c: call bool [App]App.Spy::UnsetToken(class [mscorlib]System.Type, class [App]App.Instancing.InstanceId)
L_0011: pop
L_0012: ldarg.0
L_0013: call instance void [mscorlib]System.Object::Finalize()
}
So how does this work? When I switch to C# reflection the code looks perfectly fine. It even says "protected override Finalize()" but PEVerify states "bad headers" and the app does not even start with an error message.