Console.WriteLine () e la necessità di così tanti overload di argomenti?


87

Stavo sfogliando la documentazione e ho notato che il Console.WriteLine()metodo aveva diversi sovraccarichi. In particolare, la mia curiosità e parziale confusione riguarda questi:

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

Sembra ridondante. Qual è la necessità degli altri quattro sovraccarichi oltre al primo? Il primo metodo è in grado di fare tutto ciò che possono fare gli altri metodi. C'è un problema di prestazioni che stavano cercando di affrontare fornendo sovraccarichi aggiuntivi, che gestiscono fino a quattro argomenti (l'ultimo)? Il sovraccarico di passare attraverso un array di un massimo di quattro argomenti è abbastanza grande da fornire la necessità di questi sovraccarichi?

Risposte:


102

In generale hai ragione sul fatto che il primo sovraccarico può essere sufficiente per gli altri sovraccarichi. Ciò non è del tutto vero perché la paramsparola chiave non può essere utilizzata per casi indiretti come l'associazione di gruppi di metodi. Per esempio

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

Il paramssovraccarico non soddisferà questo caso, funzionerà solo quando è presente questo particolare sovraccarico

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

Questo è un caso piuttosto esoterico, però. I motivi più importanti sono i seguenti

  1. Non tutte le lingue della CLI sono necessarie per supportare la paramsparola chiave. Avere i sovraccarichi riduce il carico su quei linguaggi eliminando la necessità di creare manualmente un array per una semplice chiamata WriteLine`
  2. Prestazione. La chiamata paramsall'overload impone al chiamante di allocare un array, anche se viene eseguito in modo implicito dal compilatore. Le allocazioni sono economiche in .Net ma non sono gratuite. Piccole cose come questa si sommano rapidamente specialmente su metodi comunemente chiamati come Console.WriteLine. Avere gli altri sovraccarichi consente ai casi comuni di evitare questa allocazione

1
Avevo pensato al caso del gruppo di metodi nella mia risposta, ma sono abbastanza sicuro che la conversione del gruppo di metodi non sia stata introdotta fino a C # 2.0, mentre gli overload di WriteLine risalgono almeno a 1.1.
jaket

@jaket La comoda sintassi è stata aggiunta in C # 2.0. Ma lo stesso punto si applica se si utilizza l'esplicito new E(Console.WriteLine)in C # 1.
CodesInChaos

5
L'allocazione dell'array è persino evidente con quanto è lenta una Console.WriteLine?
Bryan Boettcher

3
@insta non è la velocità ma l'accumulo di allocazioni il problema. GC è economico non gratuito e nelle app complicate GC è spesso il fattore di prestazioni dominante. Bloccare le fonti comuni di allocazione inutile è importante per le prestazioni
JaredPar

38

Gli overload sono per la comodità dei programmi C ++ / CLI in cui la parola chiave params non esiste.


1
Questa è un'ottima risposta, anche a una grande domanda, IMHO.
Uwe Keim

1
Ahh ... in realtà ha molto senso. Peccato per me, C ++ è stata la mia prima lingua. :)
BK

3
le basi iniziano dalla prima lingua, risposta intelligente amico
dbw

4

Penso che tutti voi vi stiate dimenticando che params è stato introdotto in C # 2.0. Pertanto, gli overload esistono anche da .NET 1.1, quando la parola chiave params non lo era.


jaket ha detto che.
BK

Leggi il suo commento sulla risposta di JaredPar. Questo è uno dei motivi per cui non ha incluso la spiegazione del parametro nella sua risposta.
BK

@ Noobacode, è vero che l'ha fatto ma è dedotto (da come l'ho letto). Do un voto positivo (per quel poco che vale) ad Alan qui perché lo ha dichiarato in un maniero più diretto.
Frank V

1
Da questo collegamento la parola chiave params esiste anche in .Net 1.1
Sriram Sakthivel

1

Penso che la domanda posta abbia già le risposte buone ed esplicative di JaredPar e jaket, ma un punto che penso possa essere rilevante anche,

Penso che la facilità d'uso e la libertà per gli utenti di utilizzare una qualsiasi delle funzioni di cui sopra in base alle loro esigenze, in questo modo, c'è bisogno è molto più conveniente piuttosto che imporre loro di creare un array, quando in realtà non lo richiedono.

Penso anche ai vecchi tempi in cui ho iniziato a imparare il C # che usavo a malapena gli array e usare gli array era un compito complicato per me, assegnarli e quindi inizializzarli con i valori appropriati era davvero complicato e richiedeva anche tempo ...


3
Ma l'idea paramsè che tu possa passare un array o scrivere esplicitamente tutti gli argomenti. un metodo simile void do(params object[])può essere chiamato con do(new object[] {"some", "stuff"}o do("some", "stuff"). Non penso che il tuo punto sia esattamente applicabile qui.
Kroltan

2
@Kroltan ma puoi dire quanti principianti conoscono davvero il significato di paramse sanno se paramsc'è, allora puoi passare le variabili separate da virgole.
dbw

1
@Kroltan Anch'io non sapevo che l'uso di paramspotrebbe essere così da molto tempo e nella sezione di aiuto visualizzata in Visual Studion se ottengo array []come argomento penserò lo stesso per fornire array come argomento ....
dbw

-3

Questo non è proprio per il problema delle prestazioni in quanto tale. Tuttavia, aumentare l'usabilità è un motivo valido alla base.

Il codice qui sotto, ti darebbe una piccola panoramica.

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

Si prega di fare riferimento al collegamento: http://msdn.microsoft.com/en-us/library/aa324774(v=vs.71).aspx per ulteriori informazioni.


9
In che modo ciò aumenta l'usabilità? Il primo metodo può fare esattamente la stessa cosa degli altri quattro. Mi stai riferendo alla documentazione, mentre io ho appena detto che stavo esaminando la documentazione. So per cosa viene utilizzato questo metodo e come utilizzarlo (non sono nuovo in C # in alcun modo). Ma perché sono necessari sovraccarichi aggiuntivi oltre al primo.
BK

Penso che ciò che intende è che, per il passaggio di un solo parametro, non ha senso creare un array per mantenerlo e passarlo al metodo - perché non passare semplicemente l'unico parametro? Questa sarebbe la mia ragione per fare qualcosa del genere
KingTravisG

@ SCassidy1986: Non crei l'array quando è un metodo params, a meno che tu non lo voglia. Il compilatore ne creerà uno automaticamente. Questo è il punto di entrambi i parametri e di questa domanda.
Magus
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.