Я пробовал весь день получать действительную перегрузку для метода System.Object.Finalizer(). Мне нужно ввести финализатор (если его еще нет) в случайные классы. Сам метод должен работать очень хорошо - по крайней мере, отраженный он выглядит действительным, и я не вижу никаких проблем/ошибок CIL.C#/Cecil Создание перегрузки Finalizer
Это код, который создает перегруженный метод:
destructor = new MethodDefinition("Finalize",
MethodAttributes.Family | MethodAttributes.HideBySig | MethodAttributes.Virtual |
MethodAttributes.ReuseSlot, module.Import(typeof (void)));
baseType.Methods.Add(destructor);
Все решения, которые я нашел в Интернете (которые все являются весьма устарели, очевидно) только показать, что вы должны установить эти атрибуты - ничего больше.
Это сгенерированный компилятором версия:
.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
}
Следующий код CIL мой сгенерированный код. Самая очевидная ошибка и, вероятно, причина, по которой она не работает, - это отсутствие «.override». Я не могу понять, как я это достигаю. Я пробовал все возможное, и это просто не работает.
.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()
}
Как это работает? Когда я переключаюсь на отражение C#, код выглядит отлично. Он даже говорит «protected override Finalize()», но PEVerify указывает «плохие заголовки», и приложение даже не запускается с сообщением об ошибке.
http://stackoverflow.com/questions/8102041/how-to-create-an-override-method-using-mono-cecil this? – usr
Да. Как я сказал: Довольно сильно устарел (2011). По крайней мере, мне не удается просто установить эти атрибуты ... – SharpShade