2010年4月19日月曜日

C# 4.0 のオプショナルパラメータと名前付き引数について 2

オーバーロードの優先順位の存在

前回のエントリーで、オーバーロードの具合を試したところ、次のエラーメッセージが出力され、ビルドは失敗に終わった。

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: オプション引数・名前付き引数」記載コードを用いて、試してみると
  1. using System;  
  2.   
  3. namespace Example  
  4. {  
  5.   public class Program  
  6.   {  
  7.     static void Main(string[] args)  
  8.     {  
  9.       Sum(1);  
  10.       Sum(1, 2);  
  11.       Sum(1, 2, 3);  
  12.       Sum(1, 2, 3, 4);  
  13.     }  
  14.   
  15.     static int Sum(int x)  
  16.     {  
  17.       Console.WriteLine("Sum(x)");  
  18.       return x;  
  19.     }  
  20.   
  21.     static int Sum(int x, int y = 0, int z = 0) // 引数2つ以上でないと呼ばれない  
  22.     {  
  23.       Console.WriteLine("Sum(x, y, z)");  
  24.       return x + y + z;  
  25.     }  
  26.   
  27.     static int Sum(params int[] rest) // 引数4つ以上でないと呼ばれない  
  28.     {  
  29.       Console.WriteLine("Sum(rest)");  
  30.       var sum = 0;  
  31.       foreach (var v in rest) sum += v;  
  32.       return sum;  
  33.     }  
  34.   }  
  35. }  
  36. /* 
  37.  * Build: 
  38.  * 
  39.  *   dmcs csharp4test3.cs 
  40.  * 
  41.  * Run: 
  42.  * 
  43.  *   mono csharp4test3.exe 
  44.  * 
  45.  */  
$ 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 件のコメント:

コメントを投稿