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;
}