61

I have a question. Is it possible to call generic method using reflection in .NET? I tried the following code

var service = new ServiceClass();
Type serviceType = service.GetType();
MethodInfo method = serviceType.GetMethod("Method1", new Type[]{});
method.MakeGenericMethod(typeof(SomeClass));
var result = method.Invoke(service, null);

But it throws the following exception "Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true."

yshchohaleu
  • 815
  • 1
  • 10
  • 16

2 Answers2

137

You're not using the result of MakeGenericMethod - which doesn't change the method you call it on; it returns another object representing the constructed method. You should have something like:

method = method.MakeGenericMethod(typeof(SomeClass));
var result = method.Invoke(service, null);

(or use a different variable, of course).

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • I had the same exact problem of not realizing that `MakeGenericMethod` is a function, not a void method, I'm sure it was ha_t's issue as well. – Shimmy Weitzhandler Nov 21 '11 at 10:29
  • I just made the same mistake but it was because I inserted the line to assign the result of MakeGenericMethod but forgot to change the invoking code to use that new returned value. – Charlie Sep 04 '12 at 21:33
  • is it bad for performance ? if i have this piece of code for every byte array I receive to deserializse from ? I am using a library that i can not change, but would like to use in my project for dynamically creating those class definitions that serializer library expects !! I am able to do it but not sure if this is worth the effort, – kuldeep May 31 '20 at 21:56
  • 2
    @kuldeep: You should benchmark your code to find out the impact. It would be foolish of me to make a prediction about the impact without knowing a lot more about your system. – Jon Skeet Jun 01 '20 at 05:25
11

You need to say

method = method.MakeGenericMethod(typeof(SomeClass));

at a minumum and preferably

var constructedMethod = method.MakeGenericMethod(typeof(SomeClass));
constructedMethod.Invoke(service, null);

as instances of MethodInfo are immutable.

This is the same concept as

string s = "Foo ";
s.Trim();
Console.WriteLine(s.Length);
string t = s.Trim();
Console.WriteLine(t.Length);

causing

4
3

to print on the console.

By the way, your error message

"Late bound operations cannot be performed on types or methods for which ContainsGenericParameters is true."

if your clue that method still contains generic parameters.

jason
  • 236,483
  • 35
  • 423
  • 525