Hey Gabriel,
On Wed, Jun 2, 2010 at 6:45 PM, Gabriel Kevorkian
<[email protected]> wrote:
> If I open the original assembly in reflector, I get the following IL
> for 'PropertyCorrect' (notice the <!T> appended to the type name)
Notice the <!T> all right :)
It means that it's a generic instantiation.
> var field = type.Fields[0];
> ilProcessor.Replace(ldc0Instr, ilProcessor.Create(OpCodes.Ldsfld,
> field));
> .method public hidebysig specialname instance int32 get_Property() cil
> managed
> {
> .maxstack 8
> L_0000: ldsfld int32 MyAssembly.A`1::field
> L_0005: ret
> }
While here you simply give the field definition of the type
definition. Which is not possible for generic types. And that for
methods and fields. You always have to create instantiations.
> and when I run PEVerify on that assembly, I get the following error:
>
> Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.1
> Copyright (c) Microsoft Corporation. All rights reserved.
>
> [IL]: Error: [I:\Work\dev.scratch\C#\CecilLoadFrom_Issue
> \CecilGenerics_Issue\bin
> \Release\MyAssembly.dll : MyAssembly.A`1[T]::get_Property][offset
> 0x00000000]Sys
> tem.BadImageFormatException: Fields inside generic classes must be
> referenced us
> ing MemberRefs, even in the same module as the class. [HRESULT
> 0x8007000B] - An
> attempt was made to load a program with an incorrect format.
Which is pretty much what peverify is complaining about.
> var fieldRef = new FieldReference(field.Name, field.FieldType)
> { DeclaringType = field.DeclaringType };
> ilProcessor.Replace(ldc0Instr, ilProcessor.Create(OpCodes.Ldsfld,
> fieldRef));
That's not enough. The issue here is with the declaring type.
If you want to create a proper field reference from scratch, here's how:
var assembly = AssemblyDefinition.ReadAssembly(@"MyAssembly.dll", new
ReaderParameters() { ReadSymbols = true });
var type = assembly.MainModule.Types.FirstOrDefault(t =>
"A`1".Equals(t.Name));
var field = type.Fields[0];
var t = type.GenericParameters [0];
var of_t = new GenericInstanceType (type);
of_t.GenericArguments.Add (t);
var field_of_t = new FieldReference (field.Name, field.FieldType) {
DeclaringType = of_t
};
That should work.
--
Jb Evain <[email protected]>
--
--
mono-cecil