Console.WriteLine () und die Notwendigkeit für so viele Argumentüberladungen?


86

Ich habe die Dokumentation durchgesehen und festgestellt, dass die Console.WriteLine()Methode mehrere Überladungen aufweist. Insbesondere betrifft meine Neugier und teilweise Verwirrung diese:

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);

Es scheint überflüssig. Was brauchen die anderen vier Überladungen zusätzlich zu der ersten? Die erste Methode kann alles, was die anderen Methoden können. Gibt es Leistungsprobleme, die durch die Bereitstellung zusätzlicher Überlastungen behoben werden sollten, die bis zu vier Argumente verarbeiten (letztes)? Ist der Aufwand für das Durchlaufen eines Arrays mit bis zu vier Argumenten groß genug, um diese Überlastungen zu vermeiden?

Antworten:


102

Im Allgemeinen haben Sie Recht, dass die erste Überlastung für die anderen Überlastungen ausreichen kann. Dies gilt jedoch nicht unbedingt, da das paramsSchlüsselwort nicht für indirekte Fälle wie die Bindung von Methodengruppen verwendet werden kann. Beispielsweise

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

Die paramsÜberlastung wird diesen Fall nicht erfüllen, sie funktioniert nur, wenn diese bestimmte Überlastung vorliegt

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

Das ist allerdings ein ziemlich esoterischer Fall. Die wichtigeren Gründe sind die folgenden

  1. Nicht jede CLI-Sprache ist erforderlich, um das paramsSchlüsselwort zu unterstützen . Durch die Überlastung wird die Belastung dieser Sprachen verringert, da kein Array mehr manuell für einen einfachen WriteLine-Aufruf erstellt werden muss
  2. Performance. Das Aufrufen der paramsÜberladung zwingt den Aufrufer, ein Array zuzuweisen, selbst wenn dies implizit vom Compiler ausgeführt wird. Zuweisungen sind in .Net billig, aber nicht kostenlos. Kleinigkeiten wie diese summieren sich schnell, besonders bei häufig genannten Methoden wie Console.WriteLine. Wenn die anderen Überlastungen vorhanden sind, können die allgemeinen Fälle diese Zuordnung vermeiden

1
Ich hatte in meiner Antwort über den Fall der Methodengruppe nachgedacht, bin mir aber ziemlich sicher, dass die Konvertierung der Methodengruppe erst in C # 2.0 eingeführt wurde, während die WriteLine-Überladungen auf mindestens 1.1 zurückgehen.
Jaket

@jaket Die praktische Syntax wurde in C # 2.0 hinzugefügt. Der gleiche Punkt gilt jedoch, wenn Sie das explizite new E(Console.WriteLine)in C # 1 verwenden.
CodesInChaos

4
Ist die Array-Zuweisung überhaupt erkennbar daran, wie langsam eine Console.WriteLine ist?
Bryan Boettcher

3
@insta Es ist nicht die Geschwindigkeit, sondern die Anhäufung von Zuordnungen, die das Problem sind. GC ist billig, nicht kostenlos und in komplizierten Apps ist GC oft der dominierende Leistungsfaktor. Das Stoppen gemeinsamer Quellen unnötiger Zuweisung ist wichtig für die Leistung
JaredPar

37

Die Überladungen dienen der Bequemlichkeit von C ++ / CLI-Programmen, bei denen das Schlüsselwort params nicht vorhanden ist.


1
Das ist eine großartige Antwort auf eine großartige Frage, IMHO auch.
Uwe Keim

1
Ahh ... das macht eigentlich sehr viel Sinn. Schade für mich, C ++ war meine Muttersprache. :)
BK

3
Die Grundlagen beginnen mit der ersten Sprache, kluge Antwort Kumpel
dbw

4

Ich denke, ihr alle vergisst, dass params in C # 2.0 eingeführt wurde. Daher sind die Überladungen auch in .NET 1.1 vorhanden, wenn das Schlüsselwort params dies nicht tat.


Jaket erwähnte das.
BK

Lesen Sie seinen Kommentar zu JaredPars Antwort. Dies ist einer der Gründe, warum er die Parametererklärung nicht in seine Antwort aufgenommen hat.
BK

@ Noobacode, es ist wahr, dass er es getan hat, aber es wird gefolgert (wie ich es gelesen habe). Ich gebe Alan hier eine Gegenstimme (für so wenig das wert ist), weil er es direkter formuliert hat.
Frank V

1
Von diesem Link existiert das Schlüsselwort params auch in .Net 1.1
Sriram Sakthivel

1

Ich denke, die gestellte Frage hat bereits die guten und erklärenden Antworten von JaredPar und jaket, aber ein Punkt, von dem ich denke, dass er auch relevant sein kann,

Ich denke, die Benutzerfreundlichkeit und die Freiheit für die Benutzer , eine der oben genannten Funktionen gemäß ihren Anforderungen zu verwenden, ist viel bequemer, als sie zu zwingen, ein Array zu erstellen, wenn sie es wirklich nicht benötigen.

Ich denke auch an die alten Zeiten, als ich anfing, das C # zu lernen. Ich habe kaum Arrays verwendet und Arrays zu verwenden war eine komplizierte Aufgabe für mich. Es zuzuweisen und sie dann mit den richtigen Werten zu initialisieren, war wirklich kompliziert und auch zeitaufwändig.


3
Die Idee von paramsist jedoch, dass Sie entweder ein Array übergeben oder alle Argumente explizit schreiben können. Eine Methode wie void do(params object[])kann entweder mit do(new object[] {"some", "stuff"}oder aufgerufen werden do("some", "stuff"). Ich denke nicht, dass Ihr Punkt hier genau zutreffend ist.
Kroltan

2
@Kroltan, aber können Sie sagen, wie viele Anfänger die Bedeutung von wirklich kennen paramsund sie wissen, ob paramses sie gibt, dann können Sie die Variablen als Komma getrennt übergeben.
dbw

1
@Kroltan Auch ich wusste lange nicht, dass die Verwendung von so sein paramskönnte, und wenn ich array []als Argument in Visual Studion angezeigt werde, denke ich, dass das Gleiche Array als Argument
liefert

-3

Dies ist nicht wirklich für das Leistungsproblem als solches. Die Erhöhung der Benutzerfreundlichkeit ist jedoch ein triftiger Grund dafür.

Der folgende Code gibt Ihnen einen kleinen Einblick.

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;
        }
    }
}

Weitere Informationen finden Sie unter folgendem Link: http://msdn.microsoft.com/en-us/library/aa324774(v=vs.71).aspx .


9
Wie erhöht das die Benutzerfreundlichkeit? Die erste Methode kann genau das Gleiche tun wie die anderen vier. Sie verweisen mich auf die Dokumentation, während ich gerade sagte, dass ich die Dokumentation durchgesehen habe. Ich weiß, wofür diese Methode verwendet wird und wie sie verwendet wird (ich bin keineswegs neu in C #). Aber warum sind zusätzliche Überlastungen zusätzlich zu der ersten erforderlich?
BK

Ich denke, was er meint, ist, dass es keinen Sinn macht, ein Array zu erstellen, um es zu halten, und es an die Methode zu übergeben - warum nicht einfach den einen Parameter übergeben? Das wäre mein Grund, so etwas zu tun
KingTravisG

@ SCassidy1986: Sie erstellen das Array nicht, wenn es sich um eine params-Methode handelt, es sei denn, Sie möchten. Der Compiler erstellt automatisch eine. Darum geht es bei beiden Parametern und bei dieser Frage.
Magus
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.