簡単なクラスとメインメソッドを作ってみましょう:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
bar bar = new bar();
bar.foo("a");
}
}
public class bar
{
public void foo(String a, String b = "b")
{
Console.WriteLine("Foo1");
}
}
}
これは書きます
Foo1
コンソールに。
次に、オプションのパラメーターを使用して、メソッドのオーバーロードをクラスに追加します。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Rextester
{
public class Program
{
public static void Main(string[] args)
{
bar bar = new bar();
bar.foo("a");
}
}
public class bar
{
public void foo(String a, String b = "b")
{
Console.WriteLine("Foo1");
}
public void foo(String a)
{
Console.WriteLine("Foo2");
}
}
}
これは書きます
Foo2
コンソールに。
foo(String a、String b = "b")はfoo(String a)とfoo(文字列a、文字列b)シグニチャ、オプションのパラメータのため。しかし、私は間違っていました。なぜこれが許可されるのですか?
Eric Lippertからの重要な 引用から始めるには
多くの人はこれを次のように考えているようです:
_void M(string x, bool y = false) { … whatever … }
_これは実際には、これをC#で記述する必要があった方法の構文上の砂糖です。
_void M(string x) { M(x, false); } void M(string x, bool y) { … whatever … }
_そうではありません。ここでの構文糖は宣言側ではなく、呼び出し側にあります。方法は1つだけです。オプションの引数を省略して呼び出しを行うと、コンパイラーは呼び出しサイトに引数を挿入するだけです。あれは:
_M(“hello”);
_として書き換えられます
_M(“hello”, false);
_
呼び出しサイトの書き換えとしてのC#のオプション引数の実装を本当に理解するには、シリーズ全体を読むことをお勧めします。基本的にあなたの期待
Foo(String a、String b = "b")はfoo(String a)とfoo(String a、String b)の両方の署名を表すと思います
それがどのように機能するかではありません。代わりに、foo(String a, String b = "b")
は実際にはfoo(String a, String b)
のみを表します。 Eric Lippertがあなたの直感が機能しない理由を提供する例として、foo(String a = "a", String b = "b")
があると仮定します。この場合、foo(String)
をうまく生成できません。
そのため、foo(String a, String b = "b")
とfoo(String a)
は、正当に同じクラスに属することができます(オプションのパラメーターは、宣言を変更するのではなく、呼び出し元に入力されるためです)。これはオプションのパラメーターの実装の自然な結果ですが、明らかにエラーが発生しやすいので、なぜそれが許可されないのかという疑問が依然としてあります。
私はここで決定的な答えはありませんが、実際にはC#の開発に関与している人しか言うことができませんが、Eric Lippertを別の言い方をすれば、言語のすべての機能に実装コストがあります。デザイナーが感じない機能は、実装しないだけのコストに見合う価値があります。この場合、おそらく正しくないコードを違法にすることは、明確なコストとわずかな利点しか持たない機能です(このようにオプションのパラメーターとオーバーライドを実際に混在させているのでしょうか?)。
メソッド呼び出しを作成すると、コンパイラーは、どのメソッドがどのパラメーターで呼び出されるかを判別します。 couldが呼び出されるすべてのメソッドをコンパイラーが決定するフェーズがあり、数値がゼロの場合はメッセージが表示され、複数ある場合は呼び出すのに最適なメソッドが決定されます。それが決定できない場合に不平を言う。
この場合、言語には、パラメーターが少ない関数を優先するルールがあります。個人的にはこれは良いルールだとは思いませんが、マイクロソフトは私の見解に同意しません。過負荷になりましたか
public func foo (String a, String c = "c")
警告があります。