10

デフォルトの関数引数を処理する唯一の方法は、関数のオーバーロードによるものであるというのは本当ですか?

たとえば、PHP では次のようにできます。

function foo($x, $y=0)
{
}

C#でそれを処理する最良の方法はこれでしょうか?

void foo(int x)
{
  foo(x, 0);
}

void foo(int x, int y)
{
}

ここから持ち上げた例

編集

C# の例を実際の C# にしました (Thanks Blair Conrad)

4

8 に答える 8

20

いくつかの好奇心を満たすために:

なぜ C# は既定のパラメーターをサポートしないのですか?から :

C++ などの言語では、メソッド宣言の一部としてデフォルト値を含めることができます。

void Process(従業員従業員、bool ボーナス = false)

このメソッドは、次のいずれかで呼び出すことができます。

a.Process(従業員、真);

また

a.Process(従業員);

2 番目のケースでは、パラメータ Bonus が false に設定されています。

C# にはこの機能がありません。

この機能がない理由の 1 つは、機能の特定の実装に関連しています。C++ の世界では、ユーザーが次のように記述した場合:

a.Process(従業員);

コンパイラが生成する

a.process(従業員、false);

つまり、コンパイラは、メソッド プロトタイプで指定されたデフォルト値を取得し、それをメソッド呼び出しに入れます。これは、ユーザーが 2 番目のパラメーターとして 'false' を記述したかのようです。残念ながら、クラスのユーザーに再コンパイルを強制せずにそのデフォルト値を変更する方法はありません。

この点では、オーバーロード モデルの方がうまく機能します。フレームワークの作成者は 2 つの別個のメソッドを定義するだけで、単一パラメーターのメソッドが 2 つのパラメーターのメソッドを呼び出します。これにより、フレームワークにデフォルト値が保持され、必要に応じて変更できます。

コンパイラが C++ 定義のようなものを取得してオーバーロードを生成することは可能ですが、その方法にはいくつかの問題があります。

1 つ目は、ユーザーが記述したコードとコンパイラが生成したコードとの相関関係があまり明確でないことです。プログラマーにとって難しくなるため、私たちは通常、可能な限り魔法を制限しようとします。2 つ目の問題は、XML ドキュメント コメントやインテリセンスなどに関係しています。コンパイラには、オーバーロードされたメソッドのドキュメント コメントを生成する方法に関する特別なルールが必要であり、Intellisense には、オーバーロードされたメソッドを単一のメソッドに折りたたむためのスマートが必要です。

オーバーロードを自分で書くのは少し不便ですが、許容できる解決策だと考えています。

于 2008-09-02T17:38:58.987 に答える
5

はい、他の人が指摘したように、パラメーター名の s を省略しない限り$、それが最善です。デフォルトのパラメーター値がない理由に興味がある人は、@Giovanni Galbo の説明を参照してください。

于 2008-09-02T17:27:26.333 に答える
4

C#FAQからの抜粋について:

そこにリストされている問題のほとんどはVB.Netで解決されました(特にインテリセンスとxmlコメントの問題)。つまり、それらは本当に赤いニシンです。C#チームが問題を解決するために利用できるコードがあります。

もう1つの理由は、クラスのユーザーに再コンパイルを強制することと関係がありますが、それも少し赤いニシンです。フレームワーククラスのデフォルト値を変更し、ユーザーが再コンパイルする必要がない場合、ユーザーがデフォルト値が変更されたことを知らないリスクがあります。 これで、実行時まで表示されない潜在的なバグがコードにあります。言い換えれば、関数をオーバーロードするという選択肢は、少なくとも同じくらい悪いことです。もちろん、これも機能の特定の実装を前提としていますが、これはよくある質問で提案されている実装です。

したがって、残りの理由(「魔法を制限しようとする」)と、オーバーロードを書き込むことが「少し不便」であるという事実(彼らが認めている)を比較検討する必要があります。個人的には、この機能を入れて、プログラマーに使用するかどうかを決めさせます。

于 2008-09-02T18:37:04.213 に答える
2

既定の引数は C++ の一部ですが、C# 3.5 の時点では、既定の引数はまだサポートされていません。オーバーロードする必要があります。1.0 以降、VB.Net で利用できます。

于 2008-09-02T17:27:48.563 に答える
0

指摘したように、これは現在 C# では利用できませんが、Sam Ng が彼のブログで議論しているように、C# 4.0 内に存在する予定です。

http://blogs.msdn.com/samng/archive/2009/02/03/named-arguments-optional-arguments-and-default-values.aspx

于 2009-03-30T10:18:04.747 に答える
0

これは仕事をしませんか?

void foo(int x):this(x, 0){}

void foo(int x, int y){
 // code here
}
于 2009-03-30T10:05:11.173 に答える
0

はい。

またはカレー。

または、クラスに抽象化し、そこでデフォルト値を使用します。

于 2008-09-02T17:28:10.510 に答える
0

いいえ、私の知る限り C# はオーバーライドをサポートしていません。はい、それが同じ効果を達成するための推奨される方法です。

于 2008-09-02T17:28:30.213 に答える