4

ここに同様の質問があります:

C# を使用してメソッドをパラメーターとして渡す

メソッドの引数と戻り値の型を知っていることを前提としています。少し違うことをしたいと思います。代わりにラムダ関数を取る System.Reflection の .GetMethod(string) のバージョンを作成しようとしています-その代わりに:

MethodInfo methodInfo = typeof(MyClass).GetMethod("AddThing");

よりコンパイルセーフなものを使用できます:

MethodInfo methodInfo = ReflectionHelper.GetMethod<MyClass>(mc => mc.AddThing);

したがって、ReflectionHelper が引数の数と戻り値の型を事前に知っていれば、答えは単純なものになります。たとえば、引数がなく、文字列が返される場合:

public static MethodInfo GetMethod<T, TReturn>(Expression<Func<T, Func<TArg, TReturn>>> expr)
{
    return ((MethodCallExpression)expr.Body).Method;
}

引数のカウント/戻り値の型が事前にわからないことを除いて、すべてのケースではなくほとんどのケースをカバーする 20 のオーバーロードでスパムするのは避けたいと思います。

それで、どうすればいいですか?

4

2 に答える 2

3

ラムダでメソッドを指定していませんmc => mc.AddThing。メソッド グループを指定しています。

あなたができることは、式にメソッド呼び出しを書くことです-実行されることはありませんが、パラメーターは必要なオーバーロードを指定するだけです.

したがって、それを使用するには、次のように記述します。

MethodInfo mi = GetMethod<MyClass>( mc => mc.AddThing( null ) );

その場合、式はActionではなく、 になる可能性がありFuncます。

public static MethodInfo<T>( Expression<Action<T>> expr )
{
  return ( ( MethodCallExpression ) x.Body ).Method;
}

式のインスペクションと同様に、ラムダが期待される形式でない場合、実行時エラーが発生しやすくなりますが、これは「魔法の」文字列を取り除くための正しい方向への一歩です。

于 2013-01-14T18:34:50.977 に答える
0

私が現在使用している回避策 (「スパム アプローチ」と呼びます) は醜いですが、限られた一連のシナリオで機能します。

public class ReflectionHelper<T>
{
    public MethodInfo GetMethod<TA1>(Expression<Func<T, Func<TA1>>> expr)
    {
        return ((MethodCallExpression)expr.Body).Method;
    }
    public MethodInfo GetMethod<TA1, TA2>(Expression<Func<T, Action<TA1, TA2>>> expr)
    {
        return ((MethodCallExpression)expr.Body).Method;
    }
    public MethodInfo GetMethod<TA1, TA2, TA3>(Expression<Func<T, Action<TA1, TA2, TA3>>> expr)
    {
        return ((MethodCallExpression)expr.Body).Method;
    }
    . . . // And more
}

さらに、さまざまな引数の数を使用して、潜在的なアクションと関数の長いリストを指定します。これにより、実際には次のように使用できます。

(new ReflectionHelper<MyClass>()).GetMethod<string>(mc => mc.SaySomething).Invoke("Hi");

だから、それは近いです-私は名前でメソッドを呼び出すだけで、そうするために偽の引数を渡すことは避けますが、その引数のタイプが何であるかをレイアウトすることにまだ巻き込まれています-私が望んでいたよりも複雑です為に。ただし、同じ名前の複数のメソッド オーバーロードがある状況では、引数の型を渡すと、メソッド リストが 1 つの特定のオーバーロードに絞り込まれます。

ただし、質問のようにメソッドを取ることができる、さらに単純なものにまだ興味があります。メソッドのオーバーロードの状況ではあいまいですが、標準の .GetMethod(string) もそうです。

于 2013-01-15T10:24:43.453 に答える