UI システムは MethodInfo からフォームを生成できます。System.Linq.Expressions の前は、リフレクションを使用して MethodInfo を取得していました (方法 1)。
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 倍遅くなります。
いくつかの数値 (StopWatch で測定):
シングル コール: 方法 1: .0000565 方法 2: .0004272 方法 3: .0019222
100000 回の呼び出し: 方法 1: .1171071 方法 2: 1.5648544 方法 3: 2.0602607
実際に式をコンパイルしたり実行したりすることはありません。パフォーマンスの違いについて誰かが説明してくれるかどうか興味があります。
更新: 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;
}