No doubt elements of this question have been asked before, but I\'m having trouble finding an answer. (Disclaimer: this is related, but separate from a recent question I as
This should give you a callable method (I'll test it in a little while). The boxing/unboxing it incurs is much faster than the security checks required for the Reflection API invocation (which happens to also require boxing).
private static Action<MethodInfo, object> BuildAccessor(Type valueType)
{
MethodInfo genericMethod = null; // <-- fill this in
MethodInfo method = genericMethod.MakeGenericMethod(new Type[] { valueType });
ParameterExpression methodInfo = Expression.Parameter(typeof(MethodInfo), "methodInfo");
ParameterExpression obj = Expression.Parameter(typeof(object), "obj");
Expression<Action<MethodInfo, object>> expr =
Expression.Lambda<Action<MethodInfo, object>>(
Expression.Call(method, methodInfo, Expression.Convert(obj, valueType)),
methodInfo,
obj);
return expr.Compile();
}
You're in luck. I actually had to do something very similar a few weeks ago.
For a detailed explanation see the above blog post, but basically the general idea is to reflect the type and manually invoke the method with an explicit set of parameters.
typeof(MyClass).GetMethod("Foo").MakeGenericMethod(new[] { param.GetType() }).Invoke(null, new[] { param });
It's not very type safe, but it does exactly what you're looking for.
class Program
{
static void Main(string[] args)
{
object str = "Hello World";
object num = 5;
object obj = new object();
Console.WriteLine("var\tvalue\t\tFoo() Type\tCallFoo() Type");
Console.WriteLine("-------------------------------------------------------");
Console.WriteLine("{0}\t{1}\t{2}\t{3}", "str", str, MyClass.Foo(str), MyClass.CallFoo(str));
Console.WriteLine("{0}\t{1}\t\t{2}\t{3}", "num", num, MyClass.Foo(num), MyClass.CallFoo(num));
Console.WriteLine("{0}\t{1}\t{2}\t{3}", "obj", obj, MyClass.Foo(obj), MyClass.CallFoo(obj));
}
}
class MyClass
{
public static Type Foo<T>(T param)
{
return typeof(T);
}
public static Type CallFoo(object param)
{
return (Type)typeof(MyClass).GetMethod("Foo").MakeGenericMethod(new[] { param.GetType() }).Invoke(null, new[] { param });
}
}
Output
var value Foo() Type CallFoo() Type
-------------------------------------------------------
str Hello World System.Object System.String
num 5 System.Object System.Int32
obj System.Object System.Object System.Object