Okay, based on your code, I see that I need to set the DeclaringType of the
MethodReference I want to call to the GenericInstanceType representing the
generic object instance.

I already have the GenericInstanceType object I need in my code, so I went
the short way - instead of using your MakeGeneric (I named my copy to
MakeHostTypeGeneric, which is not entirely accurate, but I find it better
than 'MakeGeneric'), I wrote the following extension:

public static MethodReference WithDeclaringType(this MethodReference self,
TypeReference declaringType)
{
       return new MethodReference(self.Name, self.ReturnType, declaringType)
       {
             HasThis = self.HasThis,
             ExplicitThis = self.ExplicitThis,
             CallingConvention = self.CallingConvention
       };
}

And so my code became:

GenericInstanceType genInstType = ...; // represents Nullable<int>

TypeDefinition typeDef = genInstType.Resolve();
MethodDefinition methodDef = typeDef.GetProperty("HasValue").GetMethod; //
GetProperty() is just .Properties.Single(p => p.Name == propName)

Instruction callInstr = processor.Emit(OpCodes.Call,
assembly.MainModule.Import(methodDef.WithDeclaringType(genInstType)));

However, this is still producing the same result as the original code. Based
on your code, this should work - but it doesn't. I guess I'm just being
stupid again.
Please help me, my head is exploding with generics. :(
Thank you very much!

2011/4/18 Jb Evain <[email protected]>

> Hi,
>
> On Mon, Apr 18, 2011 at 8:07 PM, ShdNx <[email protected]> wrote:
> > The solution must be very trivial, but I just cannot see it.
>
> It's indeed pretty simple when you wrap your head around how generics
> are encoded. I suggest you have a look at:
>
>
> https://github.com/jbevain/cecil/blob/master/Test/Mono.Cecil.Tests/ImportCecilTests.cs
>
> Basically you can do:
>
> // get the definitions
> TypeDefinition nullable = ...;
> MethodDefinition has_value_def = nullable.Methods.Single (m => m.Name
> == "get_HasValue");
> MethodDefinition get_value_def = nullable.Methods.Single (m => m.Name
> == "get_Value");
>
> // create the proper generic forms
> MethodReference has_value_for_int = has_value_def.MakeGeneric
> (module.TypeSystem.Int32);
> MethodReference get_value_for_int = get_value_def.MakeGeneric
> (module.TypeSystem.Int32);
>
> // import them in our target module
> MethodReference has_value_int = module.Import (has_value_for_int);
> MethodReference get_value_int = module.Import (get_value_for_int);
>
> MakeGeneric comes from the Cecil test suite. I have to find a better
> name better moving it to Cecil.Rocks.
>
> Of course this has been made verbose on purpose, but the essential is here.
>
> Jb
>
> --
> --
> mono-cecil

-- 
--
mono-cecil

Reply via email to