By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,885 Members | 1,445 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,885 IT Pros & Developers. It's quick & easy.

RE: Invoking generic method with type constraint at runtime

P: n/a
"Anders Borum" wrote:
Hi

I need to invoke a generic method determined at runtime. The method has two
arguments, a string and a generic type that is constrained to a struct:

public void Add<T>(string key, T value) where T : struct

The method is an instance member located on a class called
CmsPropertyManager. I also have a number of other "Add" methods with
different overloads.

Usually, I find it quite easy to go by reflecting the type and bind to the
method, but this time it's been really hard to determine the correct binding
parameters. When I inspect the method info, I can see that the generic
argument is having a base type of System.ValueType. However, using this as
the binding signature doesn't yield any results.

// Acquire the method info (this is the part that I'm having trouble with)
MethodInfo methodInfo = typeof(CmsPropertyManager).GetMethod("Add", new
Type[] { typeof(string), typeof(System.ValueType) });

// Acquire the generic method info
MethodInfo genericInfo = methodInfo.MakeGenericMethod(type.Type);

// Invoke with a struct (represented by o)
genericInfo.Invoke(null, new object[] { this.uiKeyName.Value, o });

Please note that once I have the method / generic method info everything is
fine and dandy; that is, if I hardcode the methodinfo reference to the right
index in the reflected type (CmsPropertyManager) the rest of the reflection
part works perfectly).

Thanks in advance.

--
With regards
Anders Borum / SphereWorks
Microsoft Certified Professional (.NET MCP)
Hi Anders,

I'm afraid the GetMethod() does not currently support filtering on generic
parameters so you will have to loop through the existing methods using
GetMethods()

MethodInfo[] methods = t.GetMethods();
MethodInfo method = null;
foreach (MethodInfo mi in methods)
{
if (mi.Name == "Add"
&& mi.ContainsGenericParameters
&& mi.GetParameters().Length == 2
&& mi.GetParameters()[0].ParameterType == typeof(string)
&& mi.GetParameters()[1].ParameterType.IsGenericParameter)
{
method = mi;
break;
}
}

Or you could make a more generic method for it

public MethodInfo GetGenericMethod(Type t, string methodName, Type[]
parameters, int genericPosition)
{
MethodInfo[] methods = t.GetMethods();
foreach (MethodInfo method in methods)
{
if (!method.ContainsGenericParameters)
continue;

if (method.Name != methodName)
continue;

ParameterInfo[] parameterinfos = method.GetParameters();
if (parameterinfos.Length != parameterinfos.Length)
continue;

bool found = true;
for (int i = 0; i < parameterinfos.Length; i++)
{
if (i == genericPosition &&
!parameterinfos[i].ParameterType.IsGenericParameter)
{
found = false;
break;
}
if (i != genericPosition && parameterinfos[i].ParameterType !=
parameters[i])
{
found = false;
break;
}
}
if (found)
return method;
}
return null;
}

--
Happy Coding!
Morten Wennevik [C# MVP]
Oct 3 '08 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.