我們的UI系統可以從MethodInfo生成一個表單。 System.Linq.Expressions之前,我們使用反射獲取MethodInfo的(方法1):提高從MethodCallExpression獲取MethodInfo的性能
MethodInfo info = typeof(ExtensionTestClass).GetMethod("InstanceMethod", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(string) }, null);
這個壞的部分是,如果我們改變InstanceMethod的簽名或名稱,代碼仍然編譯。
輸入表達式。現在我們做這個(方法2):
MethodInfo info = GetMethod<ExtensionTestClass>(x => x.InstanceMethod("defaultValue", "defaultValue"));
或本(方法3):
MethodInfo info = GetMethod<ExtensionTestClass, string, string>(x => x.InstanceMethod);
的語法是「更好」,我們得到智能感知,我們得到編譯錯誤,如果該方法沒有按不存在或簽名不匹配。但是,方法2和方法3比反射慢大約10至20倍。
一些數字(用秒錶測定):
單一呼叫: 方法1:0.0000565 方法2:0.0004272 方法3:0.0019222
100000呼叫: 方法1:0.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;
}
只是問...你有沒有嘗試過使用自定義委託?即'新SomeDelegateType(x.Method)'? – 2012-04-24 21:50:00
請顯示GetMethod的內容。很難分析不可見的代碼... – usr 2012-04-24 21:54:12
@MarcGravell,不知道我理解你的問題。 – 2012-04-24 22:30:18