Improve the performance of getting MethodInfo from MethodCallExpression

Our user interface system can generate a form from MethodInfo. Prior to System.Linq.Expressions, we received the MethodInfo method using reflection (method 1):

MethodInfo info = typeof(ExtensionTestClass).GetMethod("InstanceMethod", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(string) }, null);

The bad part about this is that if we change the signature or name of InstanceMethod, the code will still compile.

Enter expressions. Now we do this (method 2):

 MethodInfo info = GetMethod<ExtensionTestClass>(x => x.InstanceMethod("defaultValue", "defaultValue"));

or this (method 3):

MethodInfo info = GetMethod<ExtensionTestClass, string, string>(x => x.InstanceMethod);

The syntax is “better”, we get intellisense, and we get compilation errors if the method does not exist or the signature does not match. However, method 2 and method 3 are approximately 10-20 times slower than reflection.

Some numbers (measured using StopWatch):

Single call: Method 1: .0000565 Method 2: .0004272 Method 3: .0019222

100000 : 1:.1171071 2: 1,5648544 3: 2.0602607

, , - .

UPDATE: GetMethod < > :

2:

public static MethodInfo GetMethod<T>(Expression<Action<T>> target)
{
    MethodCallExpression exp = target.Body as MethodCallExpression;
    if (exp != null)
    {
        return exp.Method;
    }
    return null;
}

3:

public static MethodInfo GetMethod<T, A1, A2>(Expression<Func<T, Action<A1, A2>>> expression)
{
    var lambdaExpression = (LambdaExpression)expression;
    var unaryExpression = (UnaryExpression)lambdaExpression.Body;
    var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
    var methodInfoExpression = (ConstantExpression)methodCallExpression.Arguments.Last();
    return (MethodInfo)methodInfoExpression.Value;
}
+5
1

, , ( IL methodof, #), , ( , , ); , .

"", ; , , . , GetMethod, . , - .

IL, , ILSpy Reflector ( # #, , IL). , , , .

+1

All Articles