Console.WriteLine()と非常に多くの引数のオーバーロードが必要ですか?


87

ドキュメントを閲覧していると、Console.WriteLine()メソッドにいくつかのオーバーロードがあることに気づきました。特に、私の好奇心と部分的な混乱はこれらに関係しています:

public static void WriteLine(string format, params object[] arg);
public static void WriteLine(string format, object arg0);
public static void WriteLine(string format, object arg0, object arg1);
public static void WriteLine(string format, object arg0, object arg1, object arg2);
public static void WriteLine(string format, object arg0, object arg1, object arg2, object arg3);

冗長なようです。最初のものの上に他の4つのオーバーロードの必要性は何ですか?最初の方法は、他の方法が実行できるすべてのことを実行できます。最大4つの引数(最後の引数)を処理する追加のオーバーロードを提供することによって、彼らが取り組もうとしていたパフォーマンス上の懸念はありますか?最大4つの引数の配列を通過するオーバーヘッドは、これらのオーバーロードの必要性を提供するのに十分な大きさですか?

回答:


102

一般に、最初の過負荷が他の過負荷に対して十分である可能性があることは正しいです。ただし、paramsメソッドグループバインディングなどの間接的なケースではキーワードを使用できないため、これは厳密には当てはまりません。例えば

delegate void E(string format, object o1);
E e = Console.WriteLine;

params過負荷がこのケースを満たしていないだろう、この特定の過負荷が存在する場合、それだけで動作します

public static void WriteLine(string format, object arg0);

しかし、それはかなり難解なケースです。より重要な理由は次のとおりです

  1. paramsキーワードをサポートするためにすべてのCLI言語が必要なわけではありません。オーバーロードがあると、単純なWriteLine`呼び出し用の配列を手動で作成する必要がなくなるため、これらの言語の負担が軽減されます。
  2. パフォーマンス。paramsオーバーロードを呼び出すと、コンパイラによって暗黙的に行われた場合でも、呼び出し元は配列を割り当てる必要があります。.Netでの割り当ては安価ですが、無料ではありません。このような小さなことは、特にのような一般的に呼ばれるメソッドではすぐに加算されますConsole.WriteLine。他のオーバーロードがあると、一般的なケースでこの割り当てを回避できます

1
私は自分の答えでメソッドグループのケースについて考えていましたが、メソッドグループの変換はC#2.0まで導入されなかったと確信していますが、WriteLineのオーバーロードは少なくとも1.1にまでさかのぼります。
ジャケット2014年

@jaket便利な構文がC#2.0で追加されました。あなたが明示的に使用している場合でも、同じポイントが適用されるnew E(Console.WriteLine)C#1に
CodesInChaos

5
Console.WriteLineの速度が遅い場合でも、配列の割り当ては目立ちますか?
ブライアンベッチャー2014年

3
@insta問題は速度ではなく、割り当ての蓄積です。GCは無料ではなく安価であり、複雑なアプリではGCがパフォーマンスの主な要因になることがよくあります。不必要な割り当ての一般的なソースを停止することは、パフォーマンスにとって重要です
JaredPar 2014年

38

オーバーロードは、paramsキーワードが存在しないC ++ / CLIプログラムの便宜のためのものです。


1
それは素晴らしい質問に対する素晴らしい答えです、私見も。
Uwe Keim 2014年

1
ああ...それは実際には非常に理にかなっています。残念ながら、C ++は私の最初の言語でした。:)
BK

3
基本は第一言語から始まり、賢い答えの相棒
dbw 2014年

4

皆さんは、paramsがC#2.0で導入されたことを忘れていると思います。したがって、paramsキーワードが存在しなかった場合でも、.NET1.1からオーバーロードが存在します。


ジャケットはそれについて言及しました。
BK

JaredParの答えに関する彼のコメントを読んでください。それが彼が彼の答えにパラメータの説明を含めなかった理由の1つです。
BK

@Noobacode、彼がしたのは本当ですが、それは(私がそれを読んだ方法として)推測されています。私はここでアランに賛成票を投じます(それだけの価値があります)。彼はそれをより直接的な荘園で述べたからです。
フランクV

1
このリンクから、paramsキーワードは.Net 1.1にも存在します
Sriram Sakthivel

1

尋ねられた質問には、JaredParjaketによる良い説明的な答えがすでにあると思いますが、私が考える1つのポイントも関連している可能性があります。

ユーザーが上記の機能のいずれかを必要に応じて使いやすく自由に使用できると思います。そのため、実際には必要のない配列を作成するように強制するよりも、はるかに便利な必要があります。

私がC#学び始めた昔も、 配列をほとんど使用せず、配列を使用することは私にとって複雑な作業だったと思います。配列を割り当ててから適切な値で初期化することは、本当に複雑で時間もかかりました...


3
ただし、の考え方はparams、配列を渡すか、すべての引数を明示的に書き込むことができるようにすることです。のようなメソッドvoid do(params object[])は、do(new object[] {"some", "stuff"}またはで呼び出すことができますdo("some", "stuff")。あなたの主張がここに正確に当てはまるとは思いません。
クロルタン2014年

2
@Kroltanですが、実際に意味を知っている初心者が何人いるかわかります。params彼らparamsはそこにあるかどうかを知っているので、変数をコンマ区切りで渡すことができます。
dbw 2014年

1
私もの使用を知られていなかった@Kroltanparams長時間およびヘルプセクションでは、このようなことでした私が取得する場合のVisual Studionに表示されたarray []....私は、引数として配列を供給することと同じだと思います引数として
DBW

-3

これは、パフォーマンスの問題そのものではありません。ただし、使いやすさを向上させることは、その背後にある正当な理由です。

以下のコードは、あなたに小さな洞察を与えるでしょう。

public class TipCalculator {
    private const double tipRate = 0.18;
    public static int Main(string[] args) {
        double billTotal;
        if (args.Length == 0) {
            Console.WriteLine("usage: TIPCALC total");
            return 1;
        }
        else {
            try {
                billTotal = Double.Parse(args[0]);
            }
            catch(FormatException) {
                Console.WriteLine("usage: TIPCALC total");
                return 1;
            }
            double tip = billTotal * tipRate;
            Console.WriteLine();
            Console.WriteLine("Bill total:\t{0,8:c}", billTotal);
            Console.WriteLine("Tip total/rate:\t{0,8:c} ({1:p1})", tip, tipRate);
            Console.WriteLine(("").PadRight(24, '-'));
            Console.WriteLine("Grand total:\t{0,8:c}", billTotal + tip);
            return 0;
        }
    }
}

詳細については、次のリンクを参照してください:http://msdn.microsoft.com/en-us/library/aa324774(v = vs.71).aspx 。


9
それはどのようにユーザビリティを向上させますか?最初の方法は、他の4つの方法とまったく同じことを実行できます。あなたは私にドキュメンテーションを参照しているのですが、私はドキュメンテーションを調べていると言ったばかりです。私はそのメソッドが何に使用され、どのように使用されるかを知っています(私は決してC#に慣れていません)。しかし、なぜ最初のものに加えて追加のオーバーロードが必要なのですか。
BK

彼が意味するのは、1つのパラメーターを渡すだけでは、それを保持する配列を作成してメソッドに渡す意味がないということだと思います。1つのパラメーターを渡すだけではどうでしょうか。それがそのようなことをする私の理由です
KingTravisG 2014年

@ SCassidy1986:あなたはあなたがしたい場合を除き、それは、のparams方法だとき、配列を作成しないでください。コンパイラが自動的に作成します。それが、パラメータとこの質問の両方のポイントです。
Magus 2014年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.