Console.WriteLine () y la necesidad de tantas sobrecargas de argumentos?

87

Estaba revisando la documentación y noté que el Console.WriteLine()método tenía varias sobrecargas. Particularmente, mi curiosidad y confusión parcial se refiere a estos:

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

Parece redundante. ¿Cuál es la necesidad de las otras cuatro sobrecargas además de la primera? El primer método puede hacer todo lo que pueden hacer los otros métodos. ¿Existe un problema de rendimiento que estaban tratando de abordar proporcionando sobrecargas adicionales, que manejan hasta cuatro argumentos (el último)? ¿La sobrecarga de pasar por una matriz de hasta cuatro argumentos es lo suficientemente grande como para satisfacer la necesidad de estas sobrecargas?

BK
fuente

Respuestas:

102

En general, tiene razón en que la primera sobrecarga puede ser suficiente para las otras sobrecargas. Sin embargo, esto no es estrictamente cierto porque la paramspalabra clave no se puede usar para casos indirectos como el enlace de grupos de métodos. Por ejemplo

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

La paramssobrecarga no satisfará este caso, solo funcionará cuando esta sobrecarga en particular esté presente

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

Sin embargo, ese es un caso bastante esotérico. Las razones más importantes son las siguientes

  1. No todos los lenguajes CLI son necesarios para admitir la paramspalabra clave. Tener las sobrecargas reduce la carga de esos lenguajes al eliminar la necesidad de crear manualmente una matriz para una simple llamada WriteLine`
  2. Actuación. Llamar a la paramssobrecarga obliga a quien llama a asignar una matriz, incluso si el compilador lo hace implícitamente. Las asignaciones son baratas en .Net pero no gratuitas. Pequeñas cosas como esta se suman rápidamente, especialmente en métodos comúnmente llamados como Console.WriteLine. Tener las otras sobrecargas permite que los casos comunes eviten esta asignación
JaredPar
fuente
1
Había pensado en el caso del grupo de métodos en mi respuesta, pero estoy bastante seguro de que la conversión del grupo de métodos no se introdujo hasta C # 2.0, mientras que las sobrecargas de WriteLine se remontan al menos a 1.1.
jaket
@jaket La sintaxis conveniente se agregó en C # 2.0. Pero el mismo punto se aplica si usa el explícito new E(Console.WriteLine)en C # 1.
CodesInChaos
5
¿Se nota la asignación de matrices con lo lenta que es Console.WriteLine?
Bryan Boettcher
3
@insta no es la velocidad sino la acumulación de asignaciones lo que es el problema. GC es barato, no gratuito y, en aplicaciones complicadas, GC suele ser el factor de rendimiento dominante. Detener las fuentes comunes de asignación innecesaria es importante para el rendimiento
JaredPar
38

Las sobrecargas son para la conveniencia de los programas C ++ / CLI donde la palabra clave params no existe.

jaket
fuente
1
Esa es una gran respuesta, a una gran pregunta, en mi humilde opinión también.
Uwe Keim
1
Ahh ... eso en realidad tiene mucho sentido. Qué vergüenza, C ++ fue mi primer idioma. :)
BK
3
lo básico comienza desde el primer idioma, amigo de respuesta inteligente
dbw
4

Creo que todos ustedes están olvidando que params se introdujo en C # 2.0. Por lo tanto, las sobrecargas también existen desde .NET 1.1, cuando la palabra clave params no.

Alan
fuente
jaket mencionó eso.
BK
Lea su comentario sobre la respuesta de JaredPar. Esa es una de las razones por las que no incluyó la explicación del parámetro en su respuesta.
BK
@Noobacode, es cierto que lo hizo pero se infiere (como lo leo). Doy un voto a favor (por tan poco como valga) a Alan aquí porque lo dijo de una manera más directa.
Frank V
1
A partir de este enlace palabra clave params existen en .Net 1.1 también
Sriram Sakthivel
1

Creo que la pregunta que se tiene ya el bien y respuestas explicativas por JaredPar y jaket pero un punto lo que creo que puede ser relevante también,

Creo que la facilidad de uso y la libertad para que los usuarios usen cualquiera de las funciones anteriores de acuerdo con sus requisitos, de ahí que la necesidad sea mucho más conveniente en lugar de imponerlos para crear una matriz, cuando realmente no lo requieren.

También pienso en los viejos tiempos cuando comencé a aprender el C # Casi no usaba matrices y usar matrices era una tarea complicada para mí, asignarlas y luego inicializarlas con los valores adecuados fue realmente complicado y también consumió mucho tiempo ...

dbw
fuente
3
Pero la idea paramses que pueda pasar una matriz o escribir explícitamente todos los argumentos. un método como void do(params object[])se puede llamar con do(new object[] {"some", "stuff"}o do("some", "stuff"). No creo que su punto sea exactamente aplicable aquí.
Kroltan
2
@Kroltan, pero ¿puedes decir cuántos principiantes realmente conocen el significado de paramsy saben si paramsestá ahí, entonces puedes pasar las variables separadas por comas?
dbw
1
@Kroltan Yo tampoco sabía que el uso de paramspodría ser así durante mucho tiempo y en la sección de ayuda que se muestra en Visual Studion, si obtengo un array []argumento, pensaré lo mismo para proporcionar una matriz como argumento ...
dbw
-3

Esto no es realmente por la cuestión del rendimiento como tal. Sin embargo, aumentar la usabilidad es una razón válida detrás de esto.

El código a continuación le dará una pequeña idea.

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

Por favor, consulte el enlace: http://msdn.microsoft.com/en-us/library/aa324774(v=vs.71).aspx para obtener más información.

Deepak Sharma
fuente
9
¿Cómo aumenta eso la usabilidad? El primer método puede hacer exactamente lo mismo que los otros cuatro. Me está refiriendo a la documentación, mientras que solo dije que estaba revisando la documentación. Sé para qué se usa ese método y cómo usarlo (no soy nuevo en C # de ninguna manera). Pero, ¿por qué se necesitan sobrecargas adicionales además de la primera?
BK
Creo que lo que quiere decir es que, por solo pasar un parámetro, no tiene sentido crear una matriz para contenerlo y pasarlo al método, ¿por qué no pasar simplemente un parámetro? Esa sería mi razón para hacer algo así
KingTravisG
@ SCassidy1986: No la matriz cuando es un método params, a menos que lo desee. El compilador creará uno automáticamente. Ese es el punto de ambos params y esta pregunta.
Magus