Console.WriteLine () e a necessidade de tantas sobrecargas de argumentos?


87

Eu estava navegando na documentação e percebi que o Console.WriteLine()método tinha várias sobrecargas. Particularmente, minha curiosidade e confusão parcial se referem a estes:

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. Qual é a necessidade das outras quatro sobrecargas em cima da primeira? O primeiro método é capaz de fazer tudo o que os outros métodos podem fazer. Existe uma preocupação de desempenho que eles estavam tentando resolver fornecendo sobrecargas adicionais, que lidam com até quatro argumentos (o último)? A sobrecarga de passar por uma matriz de até quatro argumentos é grande o suficiente para fornecer a necessidade dessas sobrecargas?

Respostas:


102

Em geral, você está correto ao dizer que a primeira sobrecarga pode ser suficiente para as outras sobrecargas. No entanto, isso não é estritamente verdadeiro porque a paramspalavra - chave não pode ser usada para casos indiretos, como associação de grupo de método. Por exemplo

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

A paramssobrecarga não vai satisfazer este caso, só funcionará quando esta sobrecarga particular estiver presente

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

Esse é um caso bastante esotérico. As razões mais importantes são as seguintes

  1. Nem todo idioma CLI é necessário para suportar a paramspalavra - chave. Ter as sobrecargas reduz a carga sobre essas linguagens, removendo a necessidade de criar manualmente um array para uma chamada WriteLine simples
  2. Atuação. Chamar a paramssobrecarga força o chamador a alocar uma matriz, mesmo que isso seja feito implicitamente pelo compilador. As alocações são baratas em .Net, mas não são gratuitas. Pequenas coisas como essa somam-se rapidamente, especialmente em métodos comumente chamados como Console.WriteLine. Ter as outras sobrecargas permite os casos comuns para evitar essa alocação

1
Eu pensei sobre o caso do grupo de métodos em minha resposta, mas tenho certeza de que a conversão do grupo de métodos não foi introduzida até C # 2.0, enquanto as sobrecargas do WriteLine datam de pelo menos 1.1.
passeio de

@jaket A sintaxe conveniente foi adicionada ao C # 2.0. Mas o mesmo ponto se aplica se você usar o explícito new E(Console.WriteLine)em C # 1.
CodesInChaos

5
A alocação de array é perceptível com o quão lento é um Console.WriteLine?
Bryan Boettcher

3
@insta não é a velocidade, mas o acúmulo de alocações que são o problema. O GC é barato, não gratuito e em aplicativos complicados, o GC costuma ser o fator de desempenho dominante. Parar as fontes comuns de alocação desnecessária é importante para o desempenho
JaredPar

38

As sobrecargas são para a conveniência de programas C ++ / CLI onde a palavra-chave params não existe.


1
Essa é uma ótima resposta para uma ótima pergunta, IMHO, também.
Uwe Keim

1
Ahh ... isso realmente faz muito sentido. Que vergonha, C ++ foi minha primeira linguagem. :)
BK

3
o básico começa no primeiro idioma, amigo de resposta inteligente
dbw

4

Acho que todos vocês estão esquecendo que os parâmetros foram introduzidos no C # 2.0. Portanto, as sobrecargas também existem no .NET 1.1, quando a palavra-chave params não existia.


jaket mencionou isso.
BK

Leia seu comentário sobre a resposta de JaredPar. Essa é uma das razões pelas quais ele não incluiu a explicação param em sua resposta.
BK

@Noobacode, é verdade que sim, mas está deduzido (como eu li). Eu dou um voto positivo (pelo menos que isso valha) para Alan aqui porque ele declarou isso de uma forma mais direta.
Frank V

1
A partir deste link, a palavra-chave params também existe em .Net 1.1
Sriram Sakthivel

1

Acho que a pergunta feita já tem as respostas boas e explicativas de JaredPar e jaket, mas um ponto o que também acho que pode ser relevante,

Acho que a facilidade de uso e a liberdade para os usuários usarem qualquer uma das funções acima de acordo com a sua necessidade, aí assim, a necessidade é muito mais conveniente do que impor a criação de um array, quando na verdade não é necessário.

Também penso nos velhos tempos, quando comecei a aprender C # , quase não usava arrays e usar arrays era uma tarefa complicada para mim, atribuí-los e inicializá-los com os valores adequados era muito complicado e demorado demais ...


3
Mas a ideia paramsé que você possa passar um array ou escrever explicitamente todos os argumentos. um método como void do(params object[])pode ser chamado com do(new object[] {"some", "stuff"}ou do("some", "stuff"). Não acho que seu ponto seja exatamente aplicável aqui.
Kroltan

2
@Kroltan, mas você pode dizer quantos iniciantes realmente sabem o significado de paramse eles sabem se paramsexiste, então você pode passar as variáveis ​​separadas por vírgulas.
dbw

1
@Kroltan eu também não sabia o uso de paramspoderia ser assim por um longo tempo e na seção de ajuda exibida no Visual Studion se eu receber array []como argumento, pensarei da mesma forma para fornecer array como argumento ....
dbw

-3

Isso não é realmente para o problema de desempenho como tal. No entanto, aumentar a usabilidade é uma razão válida por trás disso.

O código abaixo dá uma pequena ideia.

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

Consulte o link: http://msdn.microsoft.com/en-us/library/aa324774(v=vs.71).aspx para obter mais informações.


9
Como isso aumenta a usabilidade? O primeiro método pode fazer exatamente a mesma coisa que os outros quatro. Você está me referindo à documentação, enquanto eu apenas disse que estava procurando na documentação. Eu sei para que esse método é usado e como usar (não sou novo em C # de forma alguma). Mas por que há necessidade de sobrecargas adicionais em cima da primeira.
BK

Acho que o que ele quis dizer é que, para apenas passar um parâmetro, não adianta criar um array para mantê-lo e passá-lo para o método - por que não apenas passar um parâmetro? Essa seria a minha razão para fazer algo assim
KingTravisG

@ SCassidy1986: Você não faz o array quando é um método params, a menos que queira. O compilador fará um automaticamente. Esse é o ponto de ambos os parâmetros e esta questão.
Magus
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.