Console.WriteLine () et la nécessité de tant de surcharges d'arguments?

87

J'étais en train de parcourir la documentation et j'ai remarqué que cette Console.WriteLine()méthode présentait plusieurs surcharges. En particulier, ma curiosité et ma confusion partielle se rapportent à ceux-ci:

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

Cela semble redondant. Quel est le besoin des quatre autres surcharges en plus de la première? La première méthode est capable de faire tout ce que les autres méthodes peuvent faire. Y a-t-il un problème de performance qu'ils essayaient de résoudre en fournissant des surcharges supplémentaires, qui gèrent jusqu'à quatre arguments (le dernier)? Est-ce que la surcharge de passer par un tableau de jusqu'à quatre arguments est suffisamment grande pour fournir la nécessité de ces surcharges?

BK
la source

Réponses:

102

En général, vous avez raison de dire que la première surcharge peut suffire aux autres surcharges. Ce n'est pas strictement vrai car le paramsmot - clé ne peut pas être utilisé pour des cas indirects comme la liaison de groupe de méthodes. Par exemple

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

La paramssurcharge ne satisfera pas ce cas, elle ne fonctionnera que lorsque cette surcharge particulière est présente

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

C'est un cas assez ésotérique cependant. Les raisons les plus importantes sont les suivantes

  1. Toutes les langues CLI ne sont pas nécessaires pour prendre en charge le paramsmot - clé. Les surcharges réduisent le fardeau de ces langues en supprimant la nécessité de créer manuellement un tableau pour un simple appel WriteLine`
  2. Performance. L'appel de la paramssurcharge force l'appelant à allouer un tableau, même si cela est fait implicitement par le compilateur. Les allocations sont bon marché en .Net mais pas gratuites. De petites choses comme celle-ci s'additionnent rapidement, en particulier sur les méthodes communément appelées comme Console.WriteLine. Avoir les autres surcharges permet aux cas courants d'éviter cette allocation
JaredPar
la source
1
J'avais pensé au cas du groupe de méthodes dans ma réponse, mais je suis à peu près sûr que la conversion de groupe de méthodes n'a pas été introduite avant C # 2.0 alors que les surcharges de WriteLine remontent à au moins 1.1.
jaket
@jaket La syntaxe pratique a été ajoutée en C # 2.0. Mais le même point s'applique si vous utilisez l'explicite new E(Console.WriteLine)en C # 1.
CodesInChaos
5
L'allocation de tableau est-elle même perceptible avec la lenteur d'une Console.WriteLine?
Bryan Boettcher
3
@insta ce n'est pas la vitesse mais l'accumulation d'allocations qui posent problème. GC est bon marché, pas gratuit et dans les applications compliquées, GC est souvent le facteur de performance dominant. Arrêter les sources communes d'allocation inutile est important pour la performance
JaredPar
38

Les surcharges sont destinées aux programmes C ++ / CLI où le mot clé params n'existe pas.

jaket
la source
1
C'est une excellente réponse, à une excellente question, à mon humble avis, aussi.
Uwe Keim
1
Ahh ... cela a en fait beaucoup de sens. Honte à moi, C ++ était ma première langue. :)
BK
3
les bases commencent à partir de la première langue, réponse intelligente mon pote
dbw
4

Je pense que vous oubliez tous que les paramètres ont été introduits dans C # 2.0. Par conséquent, les surcharges existent également à partir de .NET 1.1, alors que le mot clé params n'existait pas.

Alan
la source
jaket l'a mentionné.
BK
Lisez son commentaire sur la réponse de JaredPar. C'est l'une des raisons pour lesquelles il n'a pas inclus l'explication des paramètres dans sa réponse.
BK
@Noobacode, c'est vrai qu'il l'a fait mais c'est inféré (comme je l'ai lu). Je donne un vote positif (pour aussi peu que cela vaut la peine) à Alan ici parce qu'il l'a déclaré dans un manoir plus direct.
Frank V
1
À partir de ce lien, le mot-clé params existe également dans .Net 1.1
Sriram Sakthivel
1

Je pense que la question posée a déjà les bonnes réponses explicatives de JaredPar et jaket mais un point ce que je pense peut être pertinent aussi,

Je pense que la facilité d'utilisation et la liberté pour les utilisateurs d'utiliser l'une des fonctions ci-dessus en fonction de leurs besoins, il est beaucoup plus pratique que de les imposer pour créer un tableau, alors qu'ils n'en ont vraiment pas besoin.

Je pense aussi au bon vieux temps où j'ai commencé à apprendre le C #, je n'utilisais guère les tableaux et utiliser des tableaux était une tâche compliquée pour moi, l'attribuer puis les initialiser avec les valeurs appropriées était vraiment compliqué et prend du temps aussi ...

dbw
la source
3
Mais l'idée paramsest que vous pouvez soit passer un tableau, soit écrire explicitement tous les arguments. une méthode comme void do(params object[])peut être appelée avec do(new object[] {"some", "stuff"}ou do("some", "stuff"). Je ne pense pas que votre argument s'applique exactement ici.
Kroltan
2
@Kroltan mais pouvez-vous dire combien de débutants connaissent vraiment la signification de paramset s'ils savent si paramsc'est là, vous pouvez passer les variables séparées par des virgules.
dbw
1
@Kroltan Je ne savais pas non plus que l'utilisation de paramspourrait être comme ça pendant longtemps et dans la section d'aide affichée dans Visual Studion si j'obtiens array []comme argument, je penserai la même chose pour fournir un tableau comme argument ....
dbw
-3

Ce n'est pas vraiment le problème des performances en tant que tel. Cependant, l'augmentation de la convivialité est une raison valable derrière cela.

Le code ci-dessous, vous donnerait un petit aperçu.

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

Veuillez consulter le lien: http://msdn.microsoft.com/en-us/library/aa324774(v=vs.71).aspx pour plus d'informations.

Deepak Sharma
la source
9
Comment cela augmente-t-il la convivialité? La première méthode peut faire exactement la même chose que les quatre autres. Vous me référez à la documentation, alors que je viens de dire que je regardais la documentation. Je sais à quoi sert cette méthode et comment l'utiliser (je ne suis pas nouveau en C #). Mais pourquoi y a-t-il besoin de surcharges supplémentaires en plus de la première?
BK
Je pense que ce qu'il veut dire, c'est que pour ne passer qu'un seul paramètre, il est inutile de créer un tableau pour le contenir et de le transmettre à la méthode - pourquoi ne pas simplement passer le seul paramètre? Ce serait ma raison de faire quelque chose comme ça
KingTravisG
@ SCassidy1986: Vous ne créez pas le tableau quand c'est une méthode params, sauf si vous le souhaitez. Le compilateur en fera un automatiquement. C'est le point des deux paramètres et de cette question.
Magus