Ufa, já faz 2 semanas que eu falei de C# 4. Estou finalizando uma edição da .Net Magazine e o grupo de arquitetura, o .Net Architects, tem tomado meu tempo (para assuntos bem legais, é verdade, ainda assim…). Assim que o fechamento da .Net Magazine passar tenho um monte de coisas para escrever por aqui. Enfim, vamos lá.

Se você está chegando agora, este é o quarto post sobre o assunto. Se você não viu os posts anteriores:

  1. C# 4.0 – Quanto antes melhor – onde apresentei um resumo das novidades, além de assuntos que envolvem a nova versão da linguagem;
  2. C# 4.0: Uma linguagem dinâmica – onde apresentei as novidades do C# 4.0 que vão aproximá-lo mais de uma linguagem dinâmicas.
  3. C# 4.0: Teremos covariância e contravariância – onde apresentei a tão esperada variância do C#.

O assunto que vou tratar aqui hoje, argumentos opcionais e nomeados, é mais uma feature para o pessoal reclamar que o C# está ficando parecido com o VB. Se você está reclamando já adianto, C# e VB são linguagens irmãs, são dialetos de uma mesma lingua, e, segundo a Microsoft, vão ficar mais e mais parecido ao longo dos anos. Tudo que tiver em um vai ter no outro (o que for possível, ao menos). Não vou ficar falando que VB é uma linguagem tão profissional quanto C#, e que as duas têm prós e contras, porque já disse isso aqui antes, em um dos posts da série Polêmicas (para a qual já tenho uns 5 ou 6 assuntos guardados). Fato é: as linguagens todas vão ficar mais dinâmicas. É a influência do Ruby (e do LINQ) sobre o .Net. Você não precisa usar, mas vai perder um monte se não usar.

Na linha deste tipo de preocupação, na última reunião do grupo, o André Dias e eu estávamos conversando sobre essa história do C# vir com dinamismo, e que tem gente achando que a palavra-chave dynamic é igual a um "Dim". Não é. Depois aproveito e posto sobre isso também.

Indo então ao ponto: argumentos opcionais e nomeados. Antes, se você tinha um método, e quisesse que algum parâmetro fosse opcional, você fazia um overload:

    class Boliche
    {
        public void Derrubar(int pinos)
        {
        }
        public void Derrubar()
        {
            this.Derrubar(0);
        }
    }

Assim, chamar Boliche.Derrubar(), sem parâmetros, é o mesmo que chamar Boliche.Derrubar(0), passando zero. Funcionava perfeitamente, só que dava um trabalhão, principalmente se você tivesse um monte de overloads, além de não ser explícito para o consumidor da classe, que tinha que ficar escolhendo qual overload usar e não sabia qual o valor padrão. Afinal, o consumidor não tem acesso ao fonte necessariamente, e onde está escrito que o valor padrão é zero? Pois agora esse problema será resolvido. O C# utilizará uma sintaxe muito parecida com a do VB, onde, após a definição do nome do parâmetro, você coloca um igual e o valor padrão. No VB ainda precisa da palavra-chave "optional". No C# não precisa. É simples assim, e é uma mão na roda, livrando a gente daquele monte de overloads, para fazer algo tão simples:

    class Boliche
    {
        public void Derrubar(int pinos = 0)
        {
        }
    }

A chamada do cliente ao método fica idêntica.

Parâmetros opcionais não são nada de novo. Existe no .Net (e portanto no CLR e no CLS) desde a versão 1.0, já que eram necessários para o VB funcionar. A IL sempre gerou parâmetros opcionais para o VB. São "novidades" em uma linguagem com release de 8 anos, existente desde o VB com guaraná com rolha… Não entendo porque o C# não tem isso desde o princípio… vai ver o pessoal do Java e do C/C++ que estava migrando ia reclamar que C# era muito parecido com o VB. Vai saber…

Pois bem, isso são parâmetros opcionais. Indo em frente: Argumentos nomeados vêm de mão dadas com parâmetros opcionais. Vejam esse exemplo:

    class Boliche
    {
        public void Derrubar(int pinos = 0, int pinosRestantes = 10)
        {
        }
    }

Posso chamar direto Boliche.Derrubar(), mas isso passaria zero e dez aos parâmetros. E se eu quisesse chamar o método passando somente o segundo argumento, chamado pinosRestantes? Fácil:

        static void Main(string[] args)
        {
            var b = new Boliche();
            b.Derrubar(pinosRestantes: 7);
        }

Neste caso, estou dizendo ao compilador que quero passar somente o segundo parâmetro, e que no primeiro aceito o valor padrão, que é zero. Também muito simples.

Algumas regras:

  1. Parâmetros opcionais são sempre os últimos. Você não pode ter um parâmetro não opcional à direita de um opcional. Faz sentido se você pensar na estruturação da sintaxe.
  2. Somente constantes são aceitas como valores padrão de parâmetros opcionais. Isso pode ser um bom motivo para continuar a usar overloads em alguns casos.
  3. Argumentos nomeados podem ser especificados em qualquer ordem. Você poderia chamar, por exemplo, Boliche.Derrubar(pinosRestantes: 5, pinos: 3), sem problemas. Mas ainda que possam ser especificados em qualquer ordem, eles serão avaliados na ordem escrita no método que está chamando, e não na ordem declarada na função. Isso é importante caso você esteja chamando funções para passar valor aos parâmetros, como Boliche.Derrubar(pinosRestantes: this.ObterPinosRestantes(), pinos: this.ObterPinosDerrubados()). Neste caso, o método ObterPinosRestantes é chamado antes do método ObterPinosDerrubados. Isso pode ser um problema caso você tenha funções com efeitos colaterais, algo que deve ser evitado a todo custo (não crie uma função que retorna um valor, e altera outro no contexto quase de forma escondida, a não ser que queira problemas para depurar depois).
  4. Você pode especificar argumentos não opcionais por nome normalmente. Isso não está restrito a argumentos opcionais.

Essas features são plenamente suportadas no CTP do Visual Studio 2010 que saiu em Outubro, ao contrário das features de variância e dinamismo, que estão pela metade.

No próximo post de C# 4.0 vou falar de interop com COM, e vocês vão ver o quanto isso ajuda neste tipo de caso.


Postado na(s) categoria(s) .Net pelo giovanni bassi em 2 de dezembro de 2008 às 00:08 | Tags:

Comentários


dezembro 2. 2008 07:54
Felipe Fujiy
Algumas semanas atras li sobre o assunto num blog americano. E vi uma "falha" no caso dos argumentos nomeados. Na hora que voce os compila, ele ve no metodo qual os valores padrões e embute no codigo cliente, sua chamada ficaria:

static void Main(string[] args)  
{  
    var b = new Boliche();  
    b.Derrubar(0, 7);
}

E se você mudar a DLL com o método, mudando o padrão do primeiro argumento pra 1, o valor padrão no cliente continuara sendo 0. A solução é recompilar todos os clientes do seu metodo.

http://blog.fujiy.net/http://blog.fujiy.net/


dezembro 30. 2008 00:43
Giovanni Bassi
Felipe, é verdade. Mas isso já acontece com o Visual Basic. Acho que não vai mudar...

http://unplugged.giggio.net/http://unplugged.giggio.net/


Brazil Heberton Melo
janeiro 2. 2009 04:43
Heberton Melo
Olá Giovanni.

Estou aprendendo os conceito basico do C#, e estou com uma dúvida, poderia me explicar o que é parâmetros e argumentos?

Desde já fico muit grato mesmo.

Atenciosamente: Heberton Melo

no site


janeiro 4. 2009 14:12
Giovanni Bassi
Olá Heberton,

Neste caso, estou usando parâmetros e argumentos como sinônimos. Argumentos são os valores que você passa à uma função.
Por exemplo, na função:

public void Derrubar(int pinos = 0, int pinosRestantes = 10)  

Os parâmetros são os valores passados para "pinos" e "pinosRestantes".

http://unplugged.giggio.net/http://unplugged.giggio.net/


Brazil Tulio Henrique
abril 20. 2009 15:36
Tulio Henrique
Isso de arguntos com valor default já e muito utilizado no PHP

no site


julho 23. 2009 12:04
Audemars Piguet
Do you accept guest posts? I would love to write couple articles here.

http://discountwatchonline.biz/http://discountwatchonline.biz/


julho 23. 2009 12:08
Tommy Hilfiger
I like your blog curently we are looking for a part time article writer would you be interested?

http://thewatchshop.biz/http://thewatchshop.biz/

Comentar


(Vai mostrar seu Gravatar)

  Country flag

biuquote
  • Comentário
  • Pré-visualização
Loading



Quem é Giovanni Bassi

Giovanni Bassi Sou uma pessoa apaixonada por tecnologia e especificamente por .Net. Sou consultor independente especialista em .Net, focado em arquitetura e melhores práticas. Tenho dezenas de artigos publicados na .Net Magazine, revista da qual sou editor técnico. Ministro palestras e cursos de vez em quando, e quando dá tempo eu respiro um pouco. Mais detalhes nesta página.

Busca

Selos

Eu vou ao TechEd Brasil 2010, e você?

MVP

MCPD

MCSD

.Net Magazine

Abaixo ao if!

Calendário

«  julho 2010  »
seteququsedo
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678
Ver detalhamento de posts no calendário

Blogs interessantes

    OPMLDownload OPML file

    Postagens recentes

    Comentários recentes

    Disclaimer / Aviso
    As opiniões colocadas neste blog são minhas e pessoais e não expressam necessariamente as opiniões de meus empregadores, pareceiros e amigos. Da mesma forma, os comentários feitos por leitores do blog não expressam a minha opinião.

    © Copyright 2010 .Net Unplugged
    Log in