Strong-typed reflection / Act Cadenza
原稿に収録できるか分からないのでソースだけ載っけておきます.解説はまあ載らないことが確定したときにでも.
元ネタは Daniel Cazzulino の strong-typed reflection および id:NyaRuRu:20061129:p1
using System; using System.Linq; using System.Linq.Expressions; using System.Reflection; public static class Reflector { static MethodInfo GetMethodInfo(this Expression expression) { var findfunc = null as Func<Expression, MethodInfo>; findfunc = expr => { switch (expr.NodeType) { case ExpressionType.Lambda: return findfunc((expr as LambdaExpression).Body); case ExpressionType.Quote: return findfunc((expr as UnaryExpression).Operand); case ExpressionType.Call: var mce = expr as MethodCallExpression; return mce != null ? mce.Method : null; case ExpressionType.MemberAccess: var me = expr as MemberExpression; var pi = me.Member as PropertyInfo; return pi != null ? pi.GetGetMethod(true) : null; default: return null; } }; return findfunc(expression); } public sealed class Function<TResult> { public static MethodInfo Bind( Expression<Func<Expression<Func<TResult>>>> expr) { return expr.GetMethodInfo(); } public static MethodInfo Bind<TArg0>( Expression<Func<TArg0, Expression<Func<TResult>>>> expr) { return expr.GetMethodInfo(); } public static MethodInfo Bind<TArg0, TArg1>( Expression<Func<TArg0, TArg1, Expression<Func<TResult>>>> expr) { return expr.GetMethodInfo(); } public static MethodInfo Bind<TArg0, TArg1, TArg2>( Expression<Func<TArg0, TArg1, TArg2, Expression<Func<TResult>>>> expr) { return expr.GetMethodInfo(); } } public sealed class Function { public static MethodInfo Bind<TArg0>( Expression<Func<TArg0, Expression<Action>>> expr) { return expr.GetMethodInfo(); } public static MethodInfo Bind<TArg0, TArg1>( Expression<Func<TArg0, TArg1, Expression<Action>>> expr) { return expr.GetMethodInfo(); } public static MethodInfo Bind<TArg0, TArg1, TArg2>( Expression<Func<TArg0, TArg1, TArg2, Expression<Action>>> expr) { return expr.GetMethodInfo(); } public static MethodInfo Bind<TArg0, TArg1, TArg2, TArg3>( Expression<Func<TArg0, TArg1, TArg2, TArg3, Expression<Action>>> expr) { return expr.GetMethodInfo(); } } }
使い方はこんな感じ.
// DateTime.get_Now : () -> DateTime var mi1 = Reflector.Function<DateTime>.Bind( () => () => DateTime.Now); // Array.Sort<T>(T[]) : int[] -> () var mi2 = Reflector.Function.Bind( (int[] array) => () => Array.Sort(array)); // string.EndsWith(string) : (string -> ) string -> bool var mi3 = Reflector.Function<bool>.Bind( (string s1, string s2) => () => s1.EndsWith(s2));