25

オーバーロードされたメソッドが 2 つあります。1 つはオプションのパラメーターです。

void foo(string a)  { }  
void foo(string a, int b = 0) { }  

今私は電話します:

 foo("abc");

興味深いことに、最初のオーバーロードが呼び出されます。オプションの値がゼロに設定された 2 番目のオーバーロードではないのはなぜですか?

正直なところ、コンパイラがエラー、少なくとも間違ったメソッドの意図しない実行を避けるための警告をもたらすことを期待していました。

この動作の理由は何ですか? C# チームがそのように定義したのはなぜですか?

4

3 に答える 3

33

MSDNから:

2つの候補が同等に良好であると判断された場合、呼び出しで引数が省略されたオプションのパラメーターを持たない候補が優先されます。これは、パラメータが少ない候補者の過負荷解決における一般的な好みの結果です。

于 2010-04-20T11:02:25.773 に答える
14

オプションのパラメーターを自動的に入力する必要がないオーバーロードは、必要なオーバーロードよりも優先されます。ただし、1 つの引数を自動的に入力することと、複数の引数を入力することの間には、そのような好みはありません。たとえば、これはコンパイル時エラーを引き起こします。

void Foo(int x, int y = 0, int z = 0) {}
void Foo(int x, int y = 0) {}
...
Foo(5);

Foo(5, 5) は 2 番目のメソッドに解決されることに注意してください。これは、オプションのパラメーターを自動的に入力する必要がないためです。

C# 4 仕様のセクション 7.5.3.2 から:

それ以外の場合、MP のすべてのパラメーターに対応する引数があり、MQ の少なくとも 1 つのオプションのパラメーターをデフォルトの引数で置き換える必要がある場合、MP は MQ よりも優れています。

正直に言うと、ほとんどの場合、これはほとんどの人が期待する動作だと思います。基本クラスのメソッドをミックスに導入すると奇妙になりますが、それは常に当てはまります。

于 2010-04-20T10:56:40.387 に答える
7

逆だったらと想像してみてください。お申し込みがありました。メソッドがありました:

void foo(string a)  { }   

すべてがうまくいきました。ここで、オプションのパラメーターを使用してオーバーロードをもう 1 つ追加します。

void foo(string a, int b = 0) { }  

ブーム!すべてのメソッド呼び出しは新しいメソッドに行きます。あなたがそれを望むかどうかはいつでも。メソッドのオーバーロードを追加すると、アプリケーション全体で間違ったメソッド呼び出しが発生する可能性があります。

私の見解では、この場合、あなたの (または他の誰かの) コードを壊す機会がはるかに多くなるでしょう。

また、OptionalAttributeはバージョン 4.0 まで C# では無視されていましたが、使用できました。Visual Basic などの他の言語との特定の相互運用性シナリオをサポートするために、または COM 相互運用のために、C# コードで使用した人もいます。現在、C# はそれをオプションのパラメーターに使用しています。警告/エラーを追加すると、それらのアプリケーションに重大な変更が生じる場合があります。

他にも理由はあるかもしれませんが、とりあえずこれが思い浮かびました。

于 2010-04-21T21:18:38.377 に答える