5

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

1 に答える 1

1

私の推測では、呼び出しごとにツリー自体を作成するオーバーヘッドに加えmethodofて、式ツリーを作成するために式バージョンが同じリフレクションを行うため (ただし、C# には類似物がない IL ショートカットを使用する可能性があります) 、遅いと思います。 (コンパイラが発行するコードによってキャッシュされるとは思わない); さらに、これらのツリーを読み取ってメソッドを元に戻す必要があります。

リフレクションは「遅い」かもしれませんが、実際には非常に高速です。特に、舞台裏でデータもキャッシュされていると信じているためです。したがって、一度呼び出すとGetMethod、2 番目の呼び出しが高速になります。これは、実際にはより多くの作業を行っているため、後続の式ツリー バージョンが遅い理由の別の説得力のある証拠を提供します。

IL に慣れている場合は、3 つすべてを使用してバージョンをコンパイルし、コンパイルされたイメージを ILSpy または Reflector で分析します (C# モードでは、どちらも巧妙で、式コードを C# に再構成しますが、これは良くないので、切り替えます。 IL モードへ) - 式ツリーを生成するために発行されたコードを見てみると、私の言いたいことがわかるでしょう。

于 2012-04-24T22:47:35.807 に答える