Olá pessoal. Tudo certo?!
Tenho acompanhado muita discussão sobre a utilidade do “var” no C#. Vejamos o que tem sido dito:
Nesse post, apresento minha opinião e alguns fatos.
Comecemos deixando claro que a utilização de var não implica em nenhum prejuízo de performance. O compilador infere o tipo da variável conforme o valor que está sendo atribuído.
Não há aumento no tempo de execução (não confunda “var” com “dynamic”), nem no tempo de compilação (não há trabalho adicional para o compilador, já que a análise semântica precisa identificar o tipo do valor que está sendo atribuído de qualquer forma).
“var” permite que escrevamos códigos mais simples. Não vejo o porquê escrever código assim:
Quando poderíamos escrever código assim:
O que eu vejo no primeiro código?! Uma violação clara de DRY (forcei, eu sei). Mas, considere, estamos repetindo o tipo que desejamos que a variável assuma. Estamos escrevendo código “inútil”, tanto para o compilador, quanto para quem está lendo o código.
Há cenários, porém, onde “var” fica estranho. Considere:
Não dá para “forçar a natureza”. Quando desejamos mais “abstração”, obviamente o “cast” não é a forma correta.
Honestamente, você saberia dizer qual é o tipo dessa consulta?
Não, né?! Por quê? Simples, há um tipo anônimo.
Mesmo que não use tipos anônimos, pode ser complicado inferir o tipo do resultado de uma consulta com LINQ.
Eu uso “var” sempre que posso. Acredito realmente que ele deixa meu código mais limpo E mais expressivo. Entretanto, adoraria entender melhor o porquê algumas pessoas não acham.
“var” torna o uso de LINQ muito mais simples.
Honestamente, adoro deixar “trabalho inútil” para o compilador.
Era isso.
Elemar, parabéns pelo post e pelo blog sempre que posso passo por aqui.
Não sabia que não havia perda de desempenho muito interessante
Bom sobre o post eu concordo em partes com você.
Sim com LINQ fica bem mais “elegante” e de fácil compreensão quando falamos de tipos anônimos mas no caso DRY eu acredito que as variáveis devem ter seu tipo.
Porque ?
Pelo simples fato que é mais fácil de entender o código.
Excluindo o caso do LINQ quando você pode não ter ideia do que esta retornando o uso excessivo de var me lembra muito o Dim de Vb.NET que as variáveis não precisam ter tipo, ou posso citar tambem javascript.
Eu acredito que se as variáveis tem tipos fica mais natural, você sabe que é um inteiro ou um float e não precisa verificar ou pensar na primeira atribuição de valor ao var.
Para mim é basicamente isso. Me ajudou bastante var no LINQ ainda utilizo quando preciso escrever algo rapidamente ou para testes.
Mas nada me tira da segurança e naturalidade do tipo.
Caro @gutopro,
Na expressão “var account = new Account();” o “Account()” já indica qual o tipo.
Pelo menos quando está numa na mesma linha.
Claro, é só a minha humilde opinião.
Saudações
Concordo com você Antônio mas apenas no momento de se instanciar. Veja eu não tenho nada contra o var e até gosto de usar.
Mas o que eu pretendi dizer é que o uso excessivo (fora os casos que eu já disse) me incomodam. Quando programo outras coisas por exemplo jogos(Xna ou Unity) é realmente importante saber os tipos das coisas para não se perder =D
man,
considere que o “Dim” do Vb (Dim .. As Variant), equivale ao “dynamic” do C#, não ao var.
Repare que a atribuição sempre acontece na mesma linha do var .. e o tipo acaba estando “colado” no código. Acha mesmo que o tipo não fica evidente?!
Eu também acho o var vantajoso. Eu uso conforme as regras padrão do Resharper.
Concordo totalmente. Muito mais limpo e expressivo.
Mas é questão de gosto mesmo. Tem gente que diz que é “mais fácil de entender” com o tipo ali. Vai entender!!
[]s
Não tem nem o que discutir!
Apesar de não ter utilizado muito o var, no meu ponto de vista o código fica mais limpo utilizando-o. Afinal de contas, você está trabalhando em uma variável com um nome específico, em um método específico, em uma classe específica que está em um projeto específico. Isso, na minha opinião, já seria informação suficiente para saber o que a variável em questão tem como responsabilidades no escopo atual. Além do fato de que sempre é possível colocar o “mouse” em cima da variável para identificar seu tipo.
Passei a usar “var” conforme as regras do Resharper.
Um exemplo de quando eu acho que atrapalha usar “var”:
void MeuMetodo()
{
….
var pedido = ObterPedido();
…
}
Neste exemplo, qual o tipo da variável pedido? O compilador consegue se virar bem, mas não fica claro para quem lê o código. Tenho que investigar o método ObterPedido para descobrir o tipo do retorno, por exemplo, passando o mouse sobre o método.
Será que o nome do método não é suficiente?! Enfim, entendi seu argumento.
Com certeza, obterPedido jamais retornaria um café da manhã.
Quando deixamos de ser mais imperativos e possamos a ser mais declarativos é o modelo que comunica a semântica. Não a linguagem.
Não que seja SUPER prático, mas basta deixar o mouse em cima do var que vc vai saber o tipo.
Eu já acho esse um bom caso para se usar var.
É uma abstração mais.
Outra coisa é que o próprio nome da variável já explica seu tipo.
E, se por algum motivo meio doido, for necessário alterar o tipo de retorno do método, não precisa alterar a declaração das variáveis.
Eu gosto muito deste recurso da linguagem. Acho muito elegante e funcional no aspecto de legibilidade. Sempre quando ouço alguém reclamar do var, no fundo, no fundo, está com o código um pouco bagunçado ou não me dão argumentos suficientes para não usá-lo
Concordo!
Os contra-argumentos ao uso do var sempre estão associados a exemplos em que o problema está em outra esfera, afinal quem tem 5 mil linhas de código num método com nome de váriaves “x”, “y”, “z”, o menor dos problemas do peão com certeza é o VAR.
Muito Bom, Valeu!!!
Legibilidade!
Veja:
var documentoFinanceiro = GetDocumentoFinanceiro();
Quantos tempo você precisa para ter certeza do tipo que está sendo manipulado?
Agora considere que você está lendo este código a partir do notepad, ou mesmo em um comentário de um blog..
Bom, eu leio bem mais rápido e consigo ter bem mais certeza (mesmo que não absoluta) ao ler o seguinte código:
DocumentoFinanceiroEspecializado documentoFinanceiro = GetDocumentoFinanceiro();
JP
Você está querendo dizer que o fato do método se chamar GetDocumentoFinanceiro() e a referência receber o nome de documentoFinanceiro te fariam pensar que o retorno poderia ser, por exemplo, um jpg?
Por que eu não entendo isto. Sinceramente, o que se pode esperar de uma linha destas além de um documentoFinanceiro?
Eu disse em acima, e me desculpe por repetir… mas quem comunica o código é o design (o modelo). Não a estrutura da linguagem de programação.
Isto pra mim, é em qualquer lugar. Quando estou lendo um código c#, estou lendo um código c#… se é VS2010, ou blog, ou e-mai… Pra mim dá tudo na mesma.
Legibilidade não é perdida.
Então vamos a um outro exemplo, só com classe do .NET:
var conteudo = File.ReadLines(@”c:\\arquivo.txt”);
Qual o tipo da variável?
Então Rafael,
Acho que o problema aqui é o nome da variável.
Concorda que:
var lines = File.ReadLines(@”c:\arquivo.txt”)
tornaria esse código mais claro?!
Então..
Estou querendo dizer que – no contexto do meu exemplo – o uso de var tem no mínimo o potencial de tornar o código mais difícil de ser compreendido por outros desenvolvedores.
Nesse caso o uso do tipo explícito torna o código menos frágil, no que tange a compreensão, considerando uma “quase nula entropia do design”..
É isto que estou te dizendo: Não. Não torna o código mais difícil de ser compreendido. Você está falando de um apêgo que se obtém pelo costume de se acreditar que os tipos são importantes, como faziam os antigos que nomeavam suas variáveis com o tipo prefixado (intIdade, strNome).
Este apêgo foi se desgastando à medida que os programadores compreenderam o grande problema que isso trazia pra modelagem (cliente.StrNome = “Daniel”) então droparam o tipo do nome, e descobriram que isto não comprometia a compreensão do código.
Agora, outro apêgo precisa ser desfeito: o de acreditar que o tipo explícito na declaração aumenta a compreensão (como acreditava-se que o prefixo no nome também o fazia).
Além disto, eu considero este “quase nula entropia do design” um equívoco. Afinal, a tipagem explícita te impede de simplesmente alterar o tipo do retorno sem alterar o tipo explícito a menos que eles sejam compatíveis por herança. Ora, bem sabemos que existem tipos virtualmente compatíveis mas que não possuem relação de herança (como um List e um Array, que só compartilham a implementação de IEnumerable). Se você usar var num método que retorne List e, posteriormente, mudar o retorno deste método para Array de T, provavelmente seu código não sofrerá dano (quase nula entropia do design de fato, ou seja, menos trabalho pra manter aquilo funcionando).
Por outro lado, se ao invés de usar o var, você tipar explicitamente o List, ao mudar o retorno, o compilador lhe dirá que há um erro de tipagem mesmo que todo o resto do seu código seja compatível com os dois tipos (maior entropia do design, pois maior será o trabalho para manter aquilo funcionando).
Complementando minha contribuição:
Vivo em um mundo onde código e design evoluem o tempo todo. Com várias equipes e vários devs de todos os níveis.
Onde é preciso dar manutenção no código que foi escrito por outros, com ou sem notações, com ou sem apegos.
Onde usamos APIs de terceiros e interoperamos com outras tecnologias e legados de mais de década.
A minha experiência indica que a compreensão do código é extremamente mais rápida e efetiva quando vejo o tipo explicitamente declarado ao receber o retorno de um método.
No meu contexto, o investimento de deixar o tipo explícito é irrisório e incomparável com o investimento de manter um design comunicativo por todo o sempre (nos casos em que isso é tagível).
É isso. Tenho apego à eficiência na manutenção. Minha abordagem tem sido efetiva no meu cenário:
AlgumaPistaQualquerQueSeja documentoFinanceiro = GetDocumentoFinanceiro();
Brilhante, man! Obrigado. Entretanto, ouso acreditar que nós tenhamos experiências relativamente semelhantes. E eu concluo exatamente o oposto.
Mas, vamos lá; você acha que:
List frases = new List();
é realmente algo necessário!? Eu, acho que não;
But…
Concordo com o uso de var no caso do new, pois não restam dúvidas quanto ao tipo.
E se fosse:
var tweets = timeline.ReceiveTweets();
O que você acha que poderia ter em tweets?
De todas as hipóteses, alguma específica fará diferença? Array, List, Collection, etc?
Cara… vivemos no mesmo mundo, nos mesmo contexto, várias equipes, vários devs, de todos os níveis, com o mesmo trabalho de dar manutenção em código escrito por outros e em tempos diferentes.
Se o que me impede de usar o var é o design, eu não ponho a culpa no var… ponho a culpa no design. Se meu código não comunica, não ponho a culpa na linguagem, ponho a culpa no meu código.
Minha abordagem tem sido “Se eu peço café, então espero que você me dê um café.” A AlgumaPistaQualquerQueSeja está no fato de que eu recebo o que eu peço.
Isto é tão gritante que, apesar de soar repetitivo, parece que ninguém prestou atenção: linguagens funcionais e dinamicas não trabalham com tipos. Rubistas entregam projetos.
Eis aí a prova de que isso é um apêgo desnecessário. Estamos voltando a combater o intIdade e strNome… logo mais o C# pode se tornar capaz de inferir tipos na declaração de métodos e parâmetros (como as funções do F#). Ou pior, o C# cai no limbo onde estão o Delphi e o Clipper e Ruby se estabeleça, ou Scala, ou Erlang… enfim… o que você vai fazer quando a tipagem explícita sumir? Vai voltar a declarar strNome?
A grande desvantagem do Var é ter surgido “tarde”, assim quem aprendeu .net 1 e 2 e não gosta de programar de verdade nem conhece.
Outra desvantagem é não poder usar 100% das vezes , tudo que força o pessoal a pensar devo usar isso agora … normalmente fica de lado .
Assim como outros que já comentaram, eu também procuro seguir o padrão proposto pelo Resharper.
Eu acho muito estranho esse “adoto o que o resharper recomenda”…
Quando leio o “adoto o que o resharper recomenda” leio tenho preguiça de pensar, estudar e procurar a melhor solução então deixo na mão de outras pessoas.
Sim eu gosto do R# e Não eu não uso var todo o tempo.
Eu uso var o tempo todo (se o compilador não conseguir inferir eu tento descobrir o que eu posso ter feito de errado para atrapalhá-lo) e gosto da “ajuda” que o resharper me dá pra ter este feedback. Não é que eu adote ele como orientador… mas adoro saber que ele pode me indicar “Ei… você deixou esse lixo aqui… posso tirar?”.
Elemar,
Boa tarde.
Então quer dizer que se você tiver q declarar as seguintes variaveis:
int a = metodoA();
float b = metodoB();
decimal c = metodoC();
você usaria assim?:
var a = metodoA();
var b = metodoB();
var c = metodoC();
E como ficaria isso em uma documentação de código? ou se eu te enviasse via email para vc dar uma olhada, você teria q copiar e colar no Visual Studio para colocar o mouse em cima e ver o tipo?
De forma alguma, man. O problema no exemplo que você acabou de me dar não é o var – sim, o nome das variáveis e o nome dos métodos.
Sim, eu sei que você usou apenas como exemplos. “Na vida real”, acredito que suas variáveis e seus métodos, por si só, seriam claros o suficiente para eu entender qual seria o valor das variáveis. (acho que não precisaria recorrer ao VS)
Cara… mas com esse exemplo tb não tem tipagem explícita que me faria ler essa documentação. Se você me enviasse um e-mail pra eu dar uma olhada, eu nem copiaria pro visual studio nem faria mais nada… simplesmente deletaria e responderia “por favor, reveja o modelo porque este está uma m3rd@.”
Uso “var” sempre que possível, desde que surgiu, e até então não passei por nenhum tipo de problema por isso (além do preconceito por parte de quem não conhece).
Acredito que muitos que são contra podem ter um entendimento errado a respeito de como o “var” funciona, ou simplesmente ter uma preferência por ter as coisas mais “claras”.
Faço uso do var, porém não 100% do tempo, com base nesse “apego” pela declaração explicita citado aqui eu aproveitei um projeto que estava iniciando e me dei a oportunidade de começar utilizando o var 100%.
Vou dizer que precisei caprichar um pouco mais da declaração dos métodos e variáveis, e me senti bem tendo este capricho.
Onde eu faria:
ClientesHomeBanking clientes = Clientes.ObterClientesHomeBanking();
Fiz:
var clientesHomeBanking = Clientes.ObterClientesHomeBanking();
Sendo assim, o que eu penso sobre o uso do var:
- Podemos utilizar a vontade, porém não em um projeto já iniciado com uso de declaração explícita (gosto de manter um padrão X ou Y, nunca XY).
- Devemos expor ao máximo o tipo de retorno no nome do método e variável para facilitar o a leitura e entendimento do código.
Sendo assim fica bonito!
Ótima idéia Eduardo !!!
Vou segui-la no próximo projeto e ignorar var no atual.
Valeu mesmo.
Saudações
Discussão inútil.
Quem gosta de “var”, use “var”.
Quem gosta de declaração explícita, que programe assim.
Ponto final.
Se haverão facilidades na manutenção do código ou não, isso depende de cada programador. Tem cara que vai olhar o “var” e vai saber como lidar. E tem cara que vai olhar e dizer “Meo deos, que bagunça!”.
De qualquer forma, se não sabe qual o tipo numa variável que recebe o retorno de um método, aperte F12 e descubra no próprio método.
Só concordo com a utilização do var em expressões que retornam tipos dinâmicos.
Para declaração continuo achando “feio”.
Nas variáveis to tipo Var. Por Exemplo;
var pedido = ObterPedido();
Quando eu coloco um ponto na frente da variável, Existem diversas opções para tornar a variável definida seja do tipo explicita.
Fora que no C# você pode definir um dataset usando essa variável e ou um datarow usando essa variável para mais tarde ser varrida;
Exemplo;
foreach (System.Data.DataRow row in pedido.Rows)
{
string ListValue = string.Concat(ListValue, row["Nomecampo"].ToString(), “,”);
}
Saudações a todos. Encontrei estes excelente blog procurando “Exemplos de aplicações metro no windows 8 visual studio 12″ no google.
Realmente é questão de opnião. Programador (incluindo eu) tem mania de achar que tudo que os outros escrevem esta ERRADO.
O fato é simples, se não há impacto de performance, se não causar boxing e unboxing, escolham a forma que mais gostam.
E parabéns ao post, também não sabia que “var” não causava perda de performance. Mas eu prefiro usar = new (); Eu uso o var com LINQ e anonymous;