¿Por qué los métodos que toman una cantidad ilimitada de parámetros a menudo definen sobrecargas con menos parámetros?

36

Por ejemplo, el System.IO.Path.Combinemétodo en .NET tiene las siguientes sobrecargas:

Combine(params String[])
Combine(String, String)
Combine(String, String, String)
Combine(String, String, String, String)

¿Cuál es el punto de los últimos tres?

El primero los cubriría a todos, como si miraras de cerca, usa la paramspalabra clave. El argumento de la compatibilidad con versiones anteriores solo cubriría la Combine(String, String)variante, ya que era la única versión hasta .NET 4.

Alex
fuente

Respuestas:

56

La razón principal es para el rendimiento. El azúcar sintáctico "argumentos ilimitados" es en realidad un conjunto de cadenas. Si solo está pasando una cadena, ¿por qué crear una matriz con solo una cadena? Especialmente si ~ 90% de las invocaciones de este método serán con 3 o menos argumentos, no hay necesidad del objeto de matriz de mayor peso. Es un poco más ligero en la memoria y requiere un poco menos de tiempo de procesamiento porque no necesita un bucle para definir el método. Si tiene tres cadenas, simplemente codifique tres cadenas.

Greg Burghardt
fuente
Otra cosa a tener en cuenta es que pasar Combinecon cero o un segmento de ruta ni siquiera tiene sentido, sin embargo, la paramsversión le permite hacer esto.
Mateo
44
La razón de la cantidad de sobrecargas que aceptan diferentes cantidades de argumentos no es la legibilidad. Es para el rendimiento debido a la sobrecarga incurrida al generar una matriz de cadenas y luego procesarlas. La razón para aceptar params string[]es la legibilidad.
Greg Burghardt
2
El rendimiento es de hecho la razón, y creo que es específicamente para cuando se espera que una función se llame desde dentro de los bucles . Como la anotación de Brad Abrams en la p.27 de The C # Programming Language, Third Edition dice: "[El] modelo C # crea una asignación de objeto adicional (la matriz que contiene) implícitamente en cada llamada. Esto rara vez es un problema, pero en el interior -escenarios de tipo bucle donde podría volverse ineficiente, sugerimos proporcionar sobrecargas para los casos principales y usar la paramssobrecarga solo para los casos extremos. Un ejemplo es la StringBuilder.AppendFormat()familia de sobrecargas ".
Eliah Kagan
3
@LowFlyingPelican Mono y .NET Framework no son lo mismo. Si observa la versión de .NET Framework , en realidad es una solución bastante diferente.
Alex
3
@LowFlyingPelican: la razón del marco .NET es el rendimiento. La razón de Mono para implementar ese método fue la compatibilidad API con .NET. La razón de Mono para implementar ese método de esa manera fue la simplicidad de implementación (debido a que tienen considerablemente menos recursos que Microsoft).
jhominal
4

Azúcar sintáctica.

Al manipular rutas de archivos, es extremadamente común tener una pequeña cantidad de valores fijos. En estos casos, es más conveniente usarlos directamente en lugar de tener que empaquetarlos en una matriz.

Gort the Robot
fuente
3
Con los params, ya lo estás sugiriendo. msdn.microsoft.com/en-us/library/w5zay9db.aspx No se necesita una matriz.
Thomas Junk
3
En C #, tienes un punto, @Thomas. Sin embargo, .NET también admite otros idiomas sin params.
Karl Bielefeldt
@ThomasJunk Ese enlace está muerto para mí, desafortunadamente, pero estoy seguro de que tienes razón ya que mi C # es mediocre. Acabo de ver muchas bibliotecas con muchos idiomas que hacen eso solo para permitir un código más limpio.
Gort the Robot