0

ここに私の質問の文脈があります:

一般的な手法は、メソッドのパラメーターをデリゲートではなく Lambda 式として宣言することです。これは、メソッドが式を調べて、デリゲート インスタンスの本体でメソッド呼び出しの名前を見つけるなどの興味深いことを実行できるようにするためです。

問題は、Resharper の intelli-sense 機能の一部が失われることです。メソッドのパラメーターがデリゲートとして宣言されている場合、Resharper は、このメソッドへの呼び出しを記述するときに役立ち、このメソッドに引数値として提供する x => x 構文を使用するように促します。

だから...私の質問に戻って、私は次のことをしたいと思います:

    MethodThatTakesDelegate(s => s.Length);
}

private void MethodThatTakesDelegate(Func<string, object> func)
{
    //convert func into expression
    //Expression<Func<string, object>> expr = "code I need to write"

    MethodThatTakesExpression(expr);
}


private void MethodThatTakesExpression(Expression<Func<string, object>> expr)
{
    //code here to determine the name of the property called against string (ie the Length)
}
4

3 に答える 3

2

「ラムダ式」という用語を使用している場合は、実際には「式ツリー」を意味します。

ラムダ式は、ソース コード内のビットです。

parameters => code

例えば

x => x * 2

式ツリーは、コードをデータとして表すSystem.Linq.Expressions.Expressionクラス (または派生クラスの 1 つ) のインスタンスです。

ラムダ式は、コンパイラによって式ツリー(実行時に式ツリーを生成するコード)またはデリゲート インスタンスに変換されます。

LambdaExpression (Expression のサブクラスの 1 つ)のインスタンスをデリゲートにコンパイルできますが、その逆はできません。

理論的には、場合によってはMethodBase.GetMethodBodyによって返される IL に基づいてこのような「逆コンパイラ」を作成できる可能がありますが、現在、式ツリーで表すことができないさまざまなデリゲートがあります。式ツリーは、ステートメントまたはステートメント ブロックではなくを表します。したがって、ループ、分岐 (条件を除く)、代入などはありません。.NET 4.0 ではこれが変更される可能性があると思いますが、Microsoft からの逆コンパイル手順は期待しない限り、. 1つには本当に正当な理由があります。

于 2009-01-21T15:01:50.140 に答える
0

いいえ、できません。

于 2009-01-21T14:15:56.880 に答える
0

ここであなたが望むものを達成することは不可能だと思います。コードのコメントから、MethodThatTakesExpression で割り当てを行ったプロパティの名前を取得しようとしているように見えます。これには、プロパティ アクセスのコンテキストをキャプチャする式ツリー ラムダ式が必要です。

デリゲートを MethodThatTakesDelegate に渡す時点で、このコンテキストは失われます。デリゲートは、メソッド情報に関するコンテキストではなく、メソッド アドレスのみを保存します。この変換が行われると、元に戻すことはできません。

これが不可能な理由の例は、デリゲートをサポートする名前付きメソッドさえ存在しない可能性があることです。ReflectionEmit を使用して、名前がまったくなく、メモリ内にのみ存在するメソッドを生成することができます。ただし、これを Func オブジェクトに割り当てることは可能です。

于 2009-01-21T14:12:35.967 に答える