Calling methods of generic types

444 views
Skip to first unread message

Hendry Luk

unread,
May 2, 2011, 1:48:59 AM5/2/11
to mono-...@googlegroups.com
I'm sure this question has been asked so many times before, but I can't seem to find a satisfying answer for it .

How do I get Cecil to emit a call to static method 'Something' on the following generic class?

public static class MyClass<T, Y>
{
    public static void Something(int a, string b, object c)
    {
    }
}

And I intend to call MyClass<int, string>.Something(int, string, object);

What's the right way to achieve that?

Thanks before
Hendry

Gábor Kozár

unread,
May 2, 2011, 7:22:37 AM5/2/11
to mono-...@googlegroups.com
These extension methods from Mono.Rocks can be helpful (I think I copied them as-is, just with a different name).  
 
public static TypeReference MakeGenericType(this TypeReference self, params TypeReference[] arguments)
{
      if (self.GenericParameters.Count != arguments.Length)
          throw new ArgumentException();

      var instance = new GenericInstanceType(self);
      foreach (var argument in arguments)
          instance.GenericArguments.Add(argument);

      return instance;
}
 
public static MethodReference MakeHostInstanceGeneric(this MethodReference self, params TypeReference[] arguments) 
{
      var reference = new MethodReference(self.Name, self.ReturnType, self.DeclaringType.MakeGenericType(arguments))
      {
          HasThis = self.HasThis,
          ExplicitThis = self.ExplicitThis,
          CallingConvention = self.CallingConvention
      };

      foreach (var parameter in self.Parameters)
          reference.Parameters.Add(new ParameterDefinition(parameter.ParameterType));

      foreach (var generic_parameter in self.GenericParameters)
          reference.GenericParameters.Add(new GenericParameter(generic_parameter.Name, reference));

      return reference;
 }

Then, assuming you have the TypeDefinition of MyClass<T, Y>:

myClassTypeDef.Methods.Single(m => m.Name == "Something").MakeHostInstanceGeneric(myModule.TypeSystem.Int32, myModule.TypeSystem.String);

2011/5/2 Hendry Luk <hendr...@gmail.com>
--
--
mono-cecil

Gábor Kozár

unread,
May 2, 2011, 7:25:22 AM5/2/11
to mono-...@googlegroups.com
And so you have the MethodDefinition that you want to call. You just have to emit a call or callvirt instruction with the MethodDefinition as operand.
(Sorry I accidentally pressed the Send button.)

2011/5/2 Gábor Kozár <kozar...@gmail.com>

Hendry Luk

unread,
May 2, 2011, 7:31:05 AM5/2/11
to mono-...@googlegroups.com
Cheers. Weird i could not find it in cecil.rocks today. I'll check again when im on a pc. Ta

Sent from my HTC
--
--
mono-cecil
Reply all
Reply to author
Forward
0 new messages