Nuestro sistema de IU puede generar un formulario a partir de un MethodInfo. Antes System.Linq.Expressions, nos iban a dar la MethodInfo utilizando la reflexión (método 1):Mejore el rendimiento de obtener MethodInfo desde MethodCallExpression
MethodInfo info = typeof(ExtensionTestClass).GetMethod("InstanceMethod", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(string) }, null);
Lo malo de esto es que si cambiamos el nombre de la firma o InstanceMethod, el código seguiría compilar.
Ingrese expresiones. Ahora hacemos esto (método 2):
MethodInfo info = GetMethod<ExtensionTestClass>(x => x.InstanceMethod("defaultValue", "defaultValue"));
o este (procedimiento 3):
MethodInfo info = GetMethod<ExtensionTestClass, string, string>(x => x.InstanceMethod);
La sintaxis es "mejor", obtenemos IntelliSense, y obtenemos errores de compilación si el método doesn 't existen o la firma no coincide. Sin embargo, el método 2 y el método 3 son de 10 a 20 veces más lentos que la reflexión.
Algunos números (medidos con el cronómetro):
Call individual: Método 1: 0.0000565 Método 2: 0.0004272 Método 3: 0.0019222
100000 Llamadas: Método 1: .1171071 Método 2: 1.5648544 Método 3: 2,0602607
en realidad no compilar la expresión o ejecutarlo, y me interesa si alguien tiene una explicación para la diferencia en el rendimiento .
ACTUALIZACIÓN: El GetMethod <> código:
Método 2:
public static MethodInfo GetMethod<T>(Expression<Action<T>> target)
{
MethodCallExpression exp = target.Body as MethodCallExpression;
if (exp != null)
{
return exp.Method;
}
return null;
}
Método 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;
}
preguntando ... ¿lo ha intentado con un delegado personalizado en su lugar? es decir, 'new SomeDelegateType (x.Method)'? –
Por favor, muestre el contenido de GetMethod. Es difícil analizar código que no es visible ... – usr
@MarcGravell, no estoy seguro de entender su pregunta. –