Por que métodos que usam uma quantidade ilimitada de parâmetros geralmente definem sobrecargas com menos parâmetros?

36

Por exemplo, o System.IO.Path.Combinemétodo no .NET possui as seguintes sobrecargas:

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

Qual é o sentido dos três últimos?

O primeiro abordaria todos, como se você observasse atentamente, ele usa a paramspalavra - chave. O argumento de compatibilidade com versões anteriores cobriria apenas a Combine(String, String)variante, pois era a única versão até o .NET 4.

Alex
fonte

Respostas:

56

A principal razão é para o desempenho. O açúcar sintático dos "argumentos ilimitados" é na verdade uma matriz de Strings. Se você está passando apenas uma sequência, por que criar uma matriz com apenas uma sequência? Especialmente se ~ 90% das invocações desse método ocorrerem com 3 ou menos argumentos, não há necessidade do objeto de matriz de peso mais pesado. É um pouco mais leve na memória e leva um pouco menos de tempo de processamento, porque você não precisa de um loop para definir o método. Se você tiver três strings, basta codificar para três strings.

Greg Burghardt
fonte
Outra coisa a se notar é que passar Combinecom zero ou um segmento de caminho nem faz sentido, mas a paramsversão permite que você faça isso.
Matthew
4
A razão para o número de sobrecargas aceitar diferentes números de argumentos não é a legibilidade. É para desempenho devido à sobrecarga incorrida ao gerar uma matriz de seqüências de caracteres e depois processá-las. A razão para aceitar params string[]é a legibilidade.
Greg Burghardt
2
O desempenho é realmente o motivo, e acredito que seja especificamente para quando se espera que uma função seja chamada de loops internos . Como diz a anotação de Brad Abrams na pág. 27 da Linguagem de programação C #, terceira edição : "[O] modelo C # cria uma alocação de objeto extra (a matriz que contém) implicitamente em cada chamada. Isso raramente é um problema, mas no interior Em cenários do tipo loop, onde isso pode se tornar ineficiente, sugerimos fornecer sobrecargas para os casos principais e usar a paramssobrecarga apenas para os casos de borda. Um exemplo é a StringBuilder.AppendFormat()família de sobrecargas. "
Eliah Kagan 5/05
3
O @LowFlyingPelican Mono e o .NET Framework não são os mesmos. Se você olhar para a versão do .NET Framework , é realmente uma solução bem diferente.
Alex
3
@ LowFlyingPelican: O motivo da estrutura .NET é o desempenho. O motivo da Mono para implementar esse método foi a compatibilidade da API com o .NET. O motivo de Mono implementar esse método dessa maneira foi a simplicidade da implementação (por conta de terem recursos consideravelmente menores que a Microsoft).
Jhominal
4

Açúcar sintático.

Ao manipular caminhos de arquivo, é extremamente comum ter um pequeno número de valores fixos. Nesses casos, é mais conveniente usá-los diretamente, em vez de precisar empacotá-los em uma matriz.

Gort the Robot
fonte
3
Com os parâmetros, você já está sugerindo. msdn.microsoft.com/en-us/library/w5zay9db.aspx Não há necessidade de uma matriz.
Thomas Junk
3
Em C #, você tem um ponto, @ Thomas. No entanto, o .NET também suporta outros idiomas sem params.
Karl Bielefeldt
@ThomasJunk Esse link está morto para mim, infelizmente, mas tenho certeza que você está certo, pois meu C # é medíocre. Acabei de ver muitas bibliotecas com muitas linguagens que fazem isso apenas para permitir um código mais limpo.
Gort the Robot