3

次のコードを試しました:

class Program: ProgParent
    {

        public int Max(params int[] op)
        {
            return 0;
        }

        public int Max(int i, params int[] op)
        {
            return 1;
        }

        public int Max(int i, int j, params int[] op)
        {
            return 2;
        }

        public static void Main(string[] args)
        {
            System.Console.WriteLine((new Program()).Max(5, 6, 7, 8));
            System.Console.ReadKey();
        }
    }

利用可能な最も具体的な機能を実行し、使用します。しかし、コンパイラはこれについて警告もエラーも出しません。なんで?

4

2 に答える 2

4

C# 言語仕様には次のように書かれています。

オーバーロードの解決を実行する場合、パラメーター配列を持つメソッドは、通常の形式 [つまり、配列を渡す] またはその拡張された形式 [つまり、可変数のパラメーターを渡す] のいずれかで適用できます。メソッドの展開された形式は、メソッドの通常の形式が利用できない場合にのみ、また展開された形式と同じシグネチャを持つメソッドが同じ型でまだ宣言されていない場合にのみ利用できます。」

(少し簡略化された) 一言で言えば: オーバーロードの解決があいまいな場合、コンパイラは非 params オーバーロードを選択します。

(あなたのようなコードを違法にするのではなく)その決定の理由は次のとおりだと思います。

  • メソッドに void fn(params object[] p) というシグネチャがある場合、(object[] を渡すことによって) "通常の形式" を呼び出す何らかの方法が必要になります。したがって、コンパイラはとにかくあいまいなケースを処理する必要があります。
  • 一時配列の作成は、メソッド呼び出しよりもはるかにコストがかかるため、同じように動作するがより効率的な 1、2、3 個のパラメーターを使用して非パラメーター オーバーロードを作成することをお勧めします。(例えば String.Format のように)
于 2009-03-31T07:44:16.620 に答える
2

ビルド エラーを無視する (これはタイプミスのせいです) - どのような警告が予想または必要ですか? 一致するオーバーロードを見つけて使用しています...

厳密に言えば、配列を渡すことでさまざまなオーバーロードを呼び出すことができますが、その使用法は完全には明らかではありません。

で複数のオーバーロードがなければ、このパターンは etc (ボンネットの下の文字列を支える) などparamsで非常に頻繁に使用されます。string.Concat+

于 2009-03-31T07:08:21.497 に答える