471,086 Members | 1,092 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,086 software developers and data experts.

RE: Invoking generic method with type constraint at runtime

"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
0 2147

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

4 posts views Thread by Jethro Guo | last post: by
2 posts views Thread by Brian Richards | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.