Revision: 24847
Updated Code
at March 12, 2010 10:16 by pckujawa
Updated Code
using System;
using System.Reflection;
using System.Text;
public class Test
{
static void Main()
{
MethodInfo indexOf = typeof(string).GetMethod("IndexOf", new Type[]{typeof(char)});
MethodInfo getByteCount = typeof(Encoding).GetMethod("GetByteCount", new Type[]{typeof(string)});
Func<string, object, object> indexOfFunc = MagicMethod<string>(indexOf);
Func<Encoding, object, object> getByteCountFunc = MagicMethod<Encoding>(getByteCount);
Console.WriteLine(indexOfFunc("Hello", 'e'));
Console.WriteLine(getByteCountFunc(Encoding.UTF8, "Euro sign: \u20ac"));
}
static Func<T, object, object> MagicMethod<T>(MethodInfo method) where T : class
{
// First fetch the generic form
MethodInfo genericHelper = typeof(Test).GetMethod("MagicMethodHelper",
BindingFlags.Static | BindingFlags.NonPublic);
// Now supply the type arguments
MethodInfo constructedHelper = genericHelper.MakeGenericMethod
(typeof(T), method.GetParameters()[0].ParameterType, method.ReturnType);
// Now call it. The null argument is because it's a static method.
object ret = constructedHelper.Invoke(null, new object[] {method});
// Cast the result to the right kind of delegate and return it
return (Func<T, object, object>) ret;
}
static Func<TTarget, object, object> MagicMethodHelper<TTarget, TParam, TReturn>(MethodInfo method)
where TTarget : class
{
// Convert the slow MethodInfo into a fast, strongly typed, open delegate
Func<TTarget, TParam, TReturn> func = (Func<TTarget, TParam, TReturn>)Delegate.CreateDelegate
(typeof(Func<TTarget, TParam, TReturn>), method);
// Now create a more weakly typed delegate which will call the strongly typed one
Func<TTarget, object, object> ret = (TTarget target, object param) => func(target, (TParam) param);
return ret;
}
}
// Or, for C# 3+
public static void Main(string[] args)
{
var indexOf = typeof(string).GetMethod("IndexOf", new[] { typeof(char) });
var getByteCount = typeof(Encoding).GetMethod("GetByteCount", new[] { typeof(string) });
var indexOfFunc = MagicMethod<string>(indexOf);
var getByteCountFunc = MagicMethod<Encoding>(getByteCount);
Console.WriteLine(indexOfFunc("Hello", 'e'));
Console.WriteLine(getByteCountFunc(Encoding.UTF8, "Euro sign: \u20ac"));
}
static Func<T, object, object> MagicMethod<T>(MethodInfo method)
{
var parameter = method.GetParameters().Single();
var instance = Expression.Parameter(typeof (T), "instance");
var argument = Expression.Parameter(typeof (object), "argument");
var methodCall = Expression.Call(
instance,
method,
Expression.Convert(argument, parameter.ParameterType)
);
return Expression.Lambda<Func<T, object, object>>(
Expression.Convert(methodCall, typeof (object)),
instance, argument
).Compile();
}
Revision: 24846
Updated Code
at March 12, 2010 10:14 by pckujawa
Updated Code
using System;
using System.Reflection;
using System.Text;
public class Test
{
static void Main()
{
MethodInfo indexOf = typeof(string).GetMethod("IndexOf", new Type[]{typeof(char)});
MethodInfo getByteCount = typeof(Encoding).GetMethod("GetByteCount", new Type[]{typeof(string)});
Func<string, object, object> indexOfFunc = MagicMethod<string>(indexOf);
Func<Encoding, object, object> getByteCountFunc = MagicMethod<Encoding>(getByteCount);
Console.WriteLine(indexOfFunc("Hello", 'e'));
Console.WriteLine(getByteCountFunc(Encoding.UTF8, "Euro sign: \u20ac"));
}
static Func<T, object, object> MagicMethod<T>(MethodInfo method) where T : class
{
// First fetch the generic form
MethodInfo genericHelper = typeof(Test).GetMethod("MagicMethodHelper",
BindingFlags.Static | BindingFlags.NonPublic);
// Now supply the type arguments
MethodInfo constructedHelper = genericHelper.MakeGenericMethod
(typeof(T), method.GetParameters()[0].ParameterType, method.ReturnType);
// Now call it. The null argument is because it's a static method.
object ret = constructedHelper.Invoke(null, new object[] {method});
// Cast the result to the right kind of delegate and return it
return (Func<T, object, object>) ret;
}
static Func<TTarget, object, object> MagicMethodHelper<TTarget, TParam, TReturn>(MethodInfo method)
where TTarget : class
{
// Convert the slow MethodInfo into a fast, strongly typed, open delegate
Func<TTarget, TParam, TReturn> func = (Func<TTarget, TParam, TReturn>)Delegate.CreateDelegate
(typeof(Func<TTarget, TParam, TReturn>), method);
// Now create a more weakly typed delegate which will call the strongly typed one
Func<TTarget, object, object> ret = (TTarget target, object param) => func(target, (TParam) param);
return ret;
}
}
Revision: 24845
Initial Code
Initial URL
Initial Description
Initial Title
Initial Tags
Initial Language
at March 12, 2010 10:13 by pckujawa
Initial Code
using System;
using System.Reflection;
using System.Text;
public class Test
{
static void Main()
{
MethodInfo indexOf = typeof(string).GetMethod(\"IndexOf\", new Type[]{typeof(char)});
MethodInfo getByteCount = typeof(Encoding).GetMethod(\"GetByteCount\", new Type[]{typeof(string)});
Func<string, object, object> indexOfFunc = MagicMethod<string>(indexOf);
Func<Encoding, object, object> getByteCountFunc = MagicMethod<Encoding>(getByteCount);
Console.WriteLine(indexOfFunc(\"Hello\", \'e\'));
Console.WriteLine(getByteCountFunc(Encoding.UTF8, \"Euro sign: \\u20ac\"));
}
static Func<T, object, object> MagicMethod<T>(MethodInfo method) where T : class
{
// First fetch the generic form
MethodInfo genericHelper = typeof(Test).GetMethod(\"MagicMethodHelper\",
BindingFlags.Static | BindingFlags.NonPublic);
// Now supply the type arguments
MethodInfo constructedHelper = genericHelper.MakeGenericMethod
(typeof(T), method.GetParameters()[0].ParameterType, method.ReturnType);
// Now call it. The null argument is because it\'s a static method.
object ret = constructedHelper.Invoke(null, new object[] {method});
// Cast the result to the right kind of delegate and return it
return (Func<T, object, object>) ret;
}
static Func<TTarget, object, object> MagicMethodHelper<TTarget, TParam, TReturn>(MethodInfo method)
where TTarget : class
{
// Convert the slow MethodInfo into a fast, strongly typed, open delegate
Func<TTarget, TParam, TReturn> func = (Func<TTarget, TParam, TReturn>)Delegate.CreateDelegate
(typeof(Func<TTarget, TParam, TReturn>), method);
// Now create a more weakly typed delegate which will call the strongly typed one
Func<TTarget, object, object> ret = (TTarget target, object param) => func(target, (TParam) param);
return ret;
}
}
Initial URL
http://msmvps.com/blogs/jon_skeet/archive/2008/08/09/making-reflection-fly-and-exploring-delegates.aspx
Initial Description
Initial Title
Converting MethodInfo into a delegate instance to improve performance
Initial Tags
Initial Language
C#