How to save a value in a field of a general class (Mono.Cecil)

I use Mono.Cecil to rewrite some assemblies. For example, for a general class with a string field. I want to generate code in a method of this class that writes to this field. This is the code for this:

var origInstanceField = type.Fields.First(fld => fld.Name.Equals("_original")); InsertBeforeReturn(instanceMethod.Body, new[] { Instruction.Create(OpCodes.Ldarg_0), Instruction.Create(OpCodes.Ldstr, "genCodeToOriginal"), Instruction.Create(OpCodes.Stfld, origInstanceField) }); 

For non-general classes, it works like a charm. For generic classes, this creates poor IL. If you look at the decompiled IL, you can tell the difference compared to the same instructions that are emitted by the compiler.

 .method public hidebysig instance void FillFields() cil managed { .maxstack 8 L_0000: nop L_0001: ldarg.0 L_0002: ldstr "non-gen code to non-gen field" L_0007: stfld string TestConsole.GenericClass`1<!T>::_original L_0017: ldarg.0 L_0018: ldstr "genCodeToOriginal" L_001d: stfld string TestConsole.GenericClass`1::_original L_0022: ret } 

The field reference points to the public generic type [GenericClass <>], and not to the type type [GenericClass <T>]. I also tried a static field with the same result.
Any idea how I can get to the correct FieldDefinition?

+6
source share
1 answer

I managed to find a solution by looking at the source code of Anotar ( https://github.com/Fody/Anotar ). The trick is to create a link to the field with a type definition that refers to the instance, not the original.

 var declaringType = new GenericInstanceType(definition.DeclaringType); foreach (var parameter in definition.DeclaringType.GenericParameters) { declaringType.GenericArguments.Add(parameter); } return new FieldReference(definition.Name, definition.FieldType, declaringType); 

Using this conversion in a typeDefinition that returns a type yields the correct FieldReference. Passing common parameters to common arguments is a bit odd, but it makes sense.

+4
source

Source: https://habr.com/ru/post/984508/


All Articles