0

c#で関数の必須パラメータ(型、名前、順序)を確認するにはどうすればよいですか?

私がやりたいことは次のとおりです。

メソッド内には、異なる型 (double、int、string、enum など) の 4 つの変数があります。これらの変数はすべて、適切な関数 (つまりメソッド) に渡す必要があります。それぞれ異なるパラメーターのセットを必要とする 3 つの候補関数があります。

コードは、型が正確に一致する 4 つの入力パラメーターを持つ関数を確認し、変数をこの関数に渡す必要があります。一致する関数が見つからない場合、私のメソッドは例外を作成する必要があります。助けてくれてありがとう。

セレナ

4

3 に答える 3

1

指定されたパラメーターが正しい順序であることがわかっている場合は、各パラメーターがその位置の署名の型から割り当て可能かどうかを確認できます。それほど悪いことではありません。

public static MethodInfo CallMethod(MethodInfo[] candicateMethods, object instance, object[] parameters)
{
    foreach (var method in candicateMethods)
    {
        if (CallMethod(method, instance, parameters))
            return method;
    }
    return null;
}

private static bool CallMethod(MethodInfo method, object instance, object[] parameters)
{
    if (method.GetParameters().Length == parameters.Length
        && method.GetParameters()
        .Zip(parameters, (a, b) => new
        {
            Signature = a.ParameterType,
            Candidate = b.GetType()
        })
        .All(pair => pair.Signature.IsAssignableFrom(pair.Candidate)))
    {
        method.Invoke(instance, parameters);
        return true;
    }
    return false;
}

out/ref/params/etc も処理する必要がある場合。署名では、はるかに複雑になります。

パラメータが正しい順序になっていない場合は、順列ごとにZip/を試行する必要があります(ブランチ全体をカットする可能性があります。バックトラッキング アルゴリズムを使用すると簡単ですが、それでも非常に時間がかかる可能性があります)。Allparameters

于 2013-01-23T16:52:02.143 に答える
0

これを試して:

クラスProgram{staticvoid Main(string [] args){

        var method = typeof(Program).GetMethod("test");

        string parameterTypes = string.Join(", ", method.GetParameters().Select(x=>x.ParameterType));

        Console.WriteLine("{0} ({1})",                             
                          method.Name,
                          parameterTypes);


        Console.ReadKey();
    }



    public void test(int a, string c)
    {
    }
}
于 2013-01-23T17:43:34.797 に答える
-1

(質問は「ランタイム」マッチング(対コンパイル時間)を要求し、リフレクションでタグ付けされているため、それを念頭に置いて回答します)

リフレクションを使用すると、言及したタイプに基づいて決定を下すために必要なすべての情報を取得できます。たとえば、MethodInfo には、関連する可能性のある 2 つのメソッドが含まれています。

ReturnType: http://msdn.microsoft.com/en-us/library/system.reflection.methodinfo.returntype.aspx

GetParameters: http://msdn.microsoft.com/en-us/library/system.reflection.methodbase.getparameters.aspx

探している関数が見つかったら、.. Invoke メソッドを使用して呼び出すことができます。

http://msdn.microsoft.com/en-us/library/a89hcwhh.aspx

より具体的な例がない場合、手順は次のとおりです。

クラス内のすべての MethodInfo について:

  • パラメータを取得して型を返す
  • returntype を調べる (必要な場合)
  • パラメーターの型と戻り値の型が一致する場合、完了

コメントで述べたように、3 番目のポイントは難しい部分かもしれません。これは、オーバーロードされた最適なメソッドを選択するとき (つまり、型のみに基づいて同じ名前の複数のメソッドから選択するとき) に、コンパイラが通常行うことです。

ただし、あなたのケースは一般的な問題よりもはるかに単純かもしれません: 有限数のメソッドの 1 つ、固定数のパラメーター、要求された型 (および正確な型) のいずれかを決定する (つまり、暗黙の必要はありません)キャスト) は非常に簡単に実装できます。より多くのコンテキストを提供する必要があります。

有効な methodinfo がある場合は、params をオブジェクト配列として渡して呼び出します。警告: リフレクションはあまり効率的ではありません (極端に遅いわけでもありません!)。これは、本当に必要な場合にのみ行う必要があります。たとえば、優れた OO 設計が役に立たない場合などです。

于 2013-01-23T16:19:41.463 に答える