/ Published in: C#
Expand |
Embed | Plain Text
Copy this code and paste it in your HTML
using System; using System.Reflection; using System.Text; public class Test { static void Main() { 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 BindingFlags.Static | BindingFlags.NonPublic); // Now supply the type arguments MethodInfo constructedHelper = genericHelper.MakeGenericMethod // Now call it. The null argument is because it's a static 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 // 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 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 methodCall = Expression.Call( instance, method, Expression.Convert(argument, parameter.ParameterType) ); return Expression.Lambda<Func<T, object, object>>( instance, argument ).Compile(); }