C#4.0、およびオプションのパラメーターとオーバーロードの組み合わせにより、あいまいさに関する警告が表示されますか?
-
06-07-2019 - |
質問
C#4.0のセクションを含むJon Skeetの彼の本のアーリーアクセスバージョンを読み始めました。残念ながら、Visual Studio 2010が利用できないため、代わりにここで質問して、答えを知っている人がいるかどうかを確認したいと思いました。
次のコード、既存のコードと新しいコードが混在している場合:
public void SomeMethod(Int32 x, Int32 y) { ... }
public void SomeMethod(Int32 x, Int32 y, Int32 z = 0) { ... }
コンパイラは、定義サイトまたは呼び出しサイトのいずれかで、あいまいさの可能性について文句を言いますか?
たとえば、このコードは実際に何をしますか?
SomeClass sc = new SomeClass();
sc.SomeMethod(15, 23);
コンパイルしますか? zパラメーターなしで呼び出しますか、またはzパラメーター付きで呼び出しますか?
解決
警告なしでコンパイルされ、最初のオーバーロードが選択されます。
オプションの名前付きパラメーターの導入により、C#のオーバーロード解決メカニズムは非常に複雑になりました。この特定のケースでは、しかしそれは理にかなっています。いつものように、コンパイラは引数に一致する最も具体的なオーバーロードを選択します。
この特定のケースがC#1.0と大きく異なるとは思わない:
public void SomeMethod(Int32 x, Int32 y) { }
public void SomeMethod(Int32 x, Int32 y, params Int32[] z) { }
これは同じように機能します(オーバーロード解決に関して)。
フォローアップの回答:そうは思いません。メソッド呼び出しでデフォルトの引数を手動で指定する必要があると思います。ただし、 x
または y
パラメーターの名前が次のように異なる場合:
public void SomeMethod(Int32 x, Int32 y) { }
public void SomeMethod(Int32 t, Int32 y, Int32 z = 0) { }
次の方法で2番目のオーバーロードを選択できます:
obj.SomeMethod(t: 10, y: 20);
他のヒント
これは、「オーバーロードの解決」で説明されています。章のセクション。
コンパイラに選択可能な2つの同等のオプションがある場合、コンパイラは、オーバーロードを使用します。オーバーロードは、オプションのパラメータを優先的に使用する必要はありませんが、厳密なバイナリ選択です。 1つの供給されていないオプションパラメータと2つのオーバーロードを選択する必要がある場合、それはあいまいな状況であると見なされます。
フォローアップコメントに答えるために、オプションパラメーターを指定してオーバーロードを強制せずに使用する方法を知りません。たとえば、次のいずれも使用できません:
// Both invalid
sc.SomeMethod(15, 23, );
sc.SomeMethod(15, 23, z:)
ただし、メソッドで異なるパラメーター名を使用している場合は、それを実行できます:
public void SomeMethod(Int32 x, Int32 y) { ... }
public void SomeMethod(Int32 a, Int32 b, Int32 c = 0) { ... }
sc.SomeMethod(a: 15, b: 23); // Calls second method