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: オプション引数・名前付き引数」記載コードを用いて、試してみると
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 件のコメント:

コメントを投稿