前回のエントリーで、オーバーロードの具合を試したところ、次のエラーメッセージが出力され、ビルドは失敗に終わった。
The call is ambiguous between the following methods or properties: `Example.Program.DoSomething()' and `Example.Program.DoSomething(int, int)'
あいまいな呼出しということで、オレはさもありなん、そりゃそうかと思った。
しかし、実はそうでなく、オーバーロードの優先順位というものが決められていて、上記の様なビルドエラーになるのはおかしいことが分かった。
「++C++; // 未確認飛行 C: オプション引数・名前付き引数 (C# によるプログラミング入門)」から引用。
オプション引数や可変長引数を使った場合のオーバーロードの優先順位ですが、 オプションなし > オプションあり > 可変長引数 の順で優先されます。
「msdn: 名前付き引数と省略可能な引数 (C# プログラミング ガイド)」から引用。
オーバーロードの解決法
名前付き引数と省略可能な引数を使用すると、オーバーロードの解決に次のように影響します。
- メソッド、インデクサー、またはコンストラクターの各パラメーターが省略可能である場合、または呼び出し側ステートメントの 1 つの引数に名前または位置によって対応し、その引数をパラメーターの型に変換できる場合、そのメソッド、インデクサー、またはコンストラクターは実行の候補となります。
- 複数の候補が見つかった場合は、明示的に指定されている引数に対して、優先される変換のオーバーロードの解決規則が適用されます。省略可能なパラメーターの省略された引数は無視されます。
- 2 つの候補が同等である場合は、呼び出しで引数が省略された省略可能なパラメーターを持たない候補が優先されます。これは、比較的少ないパラメーターを持つ候補のオーバーロードの解決での一般的な優先順に従った結果です。
また、念のため、「++C++; // 未確認飛行 C: オプション引数・名前付き引数」記載コードを用いて、試してみると
using System; namespace Example { public class Program { static void Main(string[] args) { Sum(1); Sum(1, 2); Sum(1, 2, 3); Sum(1, 2, 3, 4); } static int Sum(int x) { Console.WriteLine("Sum(x)"); return x; } static int Sum(int x, int y = 0, int z = 0) // 引数2つ以上でないと呼ばれない { Console.WriteLine("Sum(x, y, z)"); return x + y + z; } static int Sum(params int[] rest) // 引数4つ以上でないと呼ばれない { Console.WriteLine("Sum(rest)"); var sum = 0; foreach (var v in rest) sum += v; return sum; } } } /* * Build: * * dmcs csharp4test3.cs * * Run: * * mono csharp4test3.exe * */
$ dmcs csharp4test3.cs csharp4test3.cs(9,7): error CS0121: The call is ambiguous between the following methods or properties: `Example.Program.Sum(int)' and `Example.Program.Sum(int, int, int)' csharp4test3.cs(15,16): (Location of the symbol related to previous error) csharp4test3.cs(21,16): (Location of the symbol related to previous error) csharp4test3.cs(10,7): error CS1501: No overload for method `Sum' takes `2' arguments Compilation failed: 2 error(s), 0 warnings
この、dmcs のサツガイ仕様は間違っとる!だが、それがいい!とはならないが、まだ初期的、部分的なサポートらしいので、改善を生暖かく期待したい。
0 件のコメント:
コメントを投稿