次の方法があるとします。
public static void MyCoolMethod(params object[] allObjects)
{
}
public static void MyCoolMethod(object oneAlone, params object[] restOfTheObjects)
{
}
私がこれを行う場合:
MyCoolMethod("Hi", "test");
どちらが呼ばれるのか、そしてその理由は?
テストは簡単です。2番目のメソッドが呼び出されます。
理由については、C#言語仕様には、あいまいな関数宣言を解決する方法に関するかなり詳細なルールがあります。インターフェース、継承、オーバーロードを取り巻くSOについては多くの質問があり、さまざまなオーバーロードが呼び出される理由の具体例がいくつかありますが、この特定のインスタンスに答えるには、次のようにします。
7.5.3.2より良い機能メンバー
より適切な関数メンバーを決定するために、元の引数リストに表示される順序で引数式自体のみを含む、簡略化された引数リストAが作成されます。
各候補関数メンバーのパラメーターリストは、次のように作成されます。
関数メンバーが拡張フォームにのみ適用可能であった場合、拡張フォームが使用されます。
対応する引数のないオプションのパラメータは、パラメータリストから削除されます
パラメータは、引数リスト内の対応する引数と同じ位置に配置されるように並べ替えられます。
そしてさらに...
パラメータタイプシーケンス{P1、P2、…、PN}と{Q1、Q2、…、QN}が同等である場合(つまり、各Piは対応するQiへのID変換を持ちます)、次のタイブレークルールが適用されます。 、より良い関数メンバーを決定するために。
MPが非ジェネリックメソッドであり、MQがジェネリックメソッドである場合、MPはMQよりも優れています。
それ以外の場合、MPが通常の形式で適用可能であり、MQにparams配列があり、拡張形式でのみ適用可能である場合、MPはMQよりも優れています。
それ以外の場合、MPにMQよりも多くの宣言済みパラメーターがある場合、MPはMQよりも優れています。これは、両方のメソッドにparams配列があり、拡張された形式でのみ適用できる場合に発生する可能性があります。
この場合、太字のタイブレークルールが適用されているようです。仕様では、params配列が通常の形式と拡張形式でどのように扱われるかについて詳しく説明していますが、最終的には、パラメーターの数とタイプに関して最も具体的なオーバーロードが呼び出されるという経験則があります。
2つ目は、コンパイラーは、paramsコレクションにフォールバックする前に、最初に明示的に宣言されたパラメーターに対して解決を試みます。
この過負荷は注意が必要です...
MyCoolMethod( "Hi"、 "test")は明らかに2番目のオーバーロードを呼び出しますが、
MyCoolMethod( "Hi"); 2番目のオーバーロードも呼び出します。私はこれをテストしました。
おそらく、両方の入力がオブジェクトであるため、コンパイラーは、渡されるものはすべてオブジェクトの配列であると想定し、最初のオーバーロードを完全に無視します。
これはおそらく、womphttp://msdn.microsoft.com/en-us/library/aa691338(v=VS.71).aspxで言及されているより優れた関数メンバーの解決に関係しています 。