Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call generic method with a given Type object? [duplicate]

I want to call my generic method with a given type object.

void Foo(Type t) {      MyGenericMethod<t>(); } 

obviously doesn't work.

How can I make it work?

like image 344
codymanix Avatar asked Sep 10 '09 22:09

codymanix


People also ask

How do you call a generic method?

To call a generic method, you need to provide types that will be used during the method invocation. Those types can be passed as an instance of NType objects initialized with particular . NET types.

How do you call a generic method in C#?

MethodInfo method = typeof(Foo). GetMethod("MyGenericMethod"); method = method. MakeGenericMethod(t); method. Invoke(this, new object[0]);

Can we overload generic methods?

Answer: Yes, we can overload a generic methods in C# as we overload a normal method in a class. Q- If we overload generic method in C# with specific data type which one would get called?

How do you find generic types?

Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.


1 Answers

Your code sample won't work, because the generic method expects a type identifier, not a an instance of the Type class. You'll have to use reflection to do it:

public class Example {      public void CallingTest()     {         MethodInfo method = typeof (Example).GetMethod("Test");         MethodInfo genericMethod = method.MakeGenericMethod(typeof (string));         genericMethod.Invoke(this, null);      }      public void Test<T>()     {         Console.WriteLine(typeof (T).Name);     } } 

Do keep in mind that this is very brittle, I'd rather suggest finding another pattern to call your method.

Another hacky solution (maybe someone can make it a bit cleaner) would be to use some expression magic:

public class Example {      public void CallingTest()     {         MethodInfo method = GetMethod<Example>(x => x.Test<object>());         MethodInfo genericMethod = method.MakeGenericMethod(typeof (string));         genericMethod.Invoke(this, null);      }      public static MethodInfo GetMethod<T>(Expression<Action<T>> expr)     {         return ((MethodCallExpression) expr.Body)             .Method             .GetGenericMethodDefinition();     }      public void Test<T>()     {         Console.WriteLine(typeof (T).Name);     } } 

Note passing the 'object' type identifier as a generic type argument in the lambda. Couldn't figure out so quickly how to get around that. Either way, this is compile-time safe I think. It just feels wrong somehow :/

like image 62
Erik van Brakel Avatar answered Sep 24 '22 17:09

Erik van Brakel