Anteriormente, fiz uma pergunta sobre por que vejo tantos exemplos usando a var
palavra - chave e obtive a resposta de que, embora seja necessário apenas para tipos anônimos, ela é usada para tornar o código de escrita 'mais rápido' / mais fácil e 'apenas porque'.
Seguindo este link ("C # 3.0 - Var Isn't Objec") , vi que ele var
é compilado no tipo correto na IL (você verá este artigo no meio do caminho).
Minha pergunta é quanto mais, se é que existe algum, código IL usando a var
palavra - chave, e seria mesmo perto de ter um nível mensurável no desempenho do código se ele fosse usado em qualquer lugar?
c#
performance
variables
var
Jeff Keslinke
fonte
fonte
var
mais definitivamente trabalham com "Localizar todas as referências" no Visual Studio 2019, portanto, se alguma vez foi quebrado, foi corrigido. Mas posso confirmar que ele funciona desde o Visual Studio 2012, então não sei por que você afirmou que não funcionou.var
não será considerado uma referênciaX
quando você usar "Localizar todas as referências"X
. Curiosamente, se você usar "Localizar todas as referências" navar
nessa declaração, ele irá mostrar-lhe as referências aX
(embora ele ainda não vai listar avar
declaração). Além disso, quando o cursor estiver ativadovar
, ele destacará todas as instâncias doX
mesmo documento (e vice-versa).Respostas:
Não há código de IL extra para a
var
palavra-chave: o IL resultante deve ser idêntico para tipos não anônimos. Se o compilador não puder criar essa IL porque não consegue descobrir qual tipo você pretendia usar, você receberá um erro do compilador.O único truque é
var
inferir um tipo exato em que você pode ter escolhido um tipo de interface ou pai, se definir o tipo manualmente.Atualização 8 anos depois
Preciso atualizar isso, pois meu entendimento mudou. Agora acredito que pode ser possível
var
afetar o desempenho na situação em que um método retorna uma interface, mas você usaria um tipo exato. Por exemplo, se você tiver este método:Considere estas três linhas de código para chamar o método:
Todos os três compilam e executam conforme o esperado. No entanto, as duas primeiras linhas não são exatamente iguais, e a terceira linha corresponderá à segunda, e não à primeira. Como a assinatura de
Foo()
é retornar umIList<int>
, é assim que o compilador criará abar3
variável.Do ponto de vista do desempenho, principalmente você não notará. No entanto, há situações em que o desempenho da terceira linha pode não ser tão rápido quanto o desempenho da primeira . À medida que você continua a usar a
bar3
variável, o compilador pode não conseguir despachar as chamadas de método da mesma maneira.Observe que é possível (provavelmente até) o jitter será capaz de apagar essa diferença, mas isso não é garantido. Geralmente, você ainda deve considerar
var
um fator não em termos de desempenho. Certamente não é como usar umadynamic
variável. Mas dizer que nunca faz diferença pode estar exagerando.fonte
var i = 42;
(o tipo de informação é int) NÃO é idêntico along i = 42;
. Portanto, em alguns casos, você pode estar fazendo suposições incorretas sobre a inferência de tipo. Isso pode causar erros de tempo de execução indescritíveis / de arestas caso o valor não se ajuste. Por esse motivo, ainda pode ser uma boa ideia ser explícito quando o valor não tiver um tipo explícito. Por exemplo,var x = new List<List<Dictionary<int, string>()>()>()
seria aceitável, masvar x = 42
é um tanto ambíguo e deve ser escrito comoint x = 42
. Mas cada um na sua ...var x = 42;
não é ambíguo. Literais inteiros são do tipoint
. Se você quer um longo literal, você escrevevar x = 42L;
.Foo
retornado aList
, em vez de umIList
, todas as três linhas serão compiladas, mas a terceira linha se comportará como a primeira linha , não a segunda.Como Joel diz, o compilador calcula em tempo de compilação o tipo var, efetivamente é apenas um truque que o compilador executa para salvar pressionamentos de tecla, por exemplo, por exemplo
é substituído por
pelo compilador antes de qualquer IL ser gerada. O IL gerado será exatamente o mesmo que se você tivesse digitado a string.
fonte
Como ninguém mencionou refletor ainda ...
Se você compilar o seguinte código C #:
Então use o refletor nele, você obtém:
Portanto, a resposta é claramente sem desempenho de tempo de execução atingido!
fonte
Para o seguinte método:
A saída IL é esta:
fonte
O compilador C # infere o tipo verdadeiro da
var
variável em tempo de compilação. Não há diferença na IL gerada.fonte
Portanto, para deixar claro, é um estilo de codificação preguiçoso. Eu prefiro tipos nativos, dada a escolha; Vou usar esse "ruído" extra para garantir que estou escrevendo e lendo exatamente o que acho que estou no momento do código / depuração. * dar de ombros *
fonte
var
afeta o desempenho; você está apenas afirmando sua opinião sobre se as pessoas devem usá-lo.int
porque ela não pode converter automaticamente o arquivofloat
, mas é exatamente o mesmo que aconteceria se você explicitamente usasseint
e depois alterasse parafloat
. De qualquer forma, sua resposta ainda não responde à pergunta "o usovar
afeta o desempenho?" (particularmente em termos de IL gerada)Acho que você não entendeu direito o que leu. Se ele é compilado para o tipo correto, então não é nenhuma diferença. Quando eu faço isso:
O compilador sabe que é um int e gera código como se eu tivesse escrito
Como diz a postagem que você vinculou, ela é compilada para o mesmo tipo. Não é uma verificação de tempo de execução ou qualquer outra coisa que exija código extra. O compilador apenas descobre qual deve ser o tipo e o usa.
fonte
Não há custo de desempenho de tempo de execução no uso de var. No entanto, eu suspeitaria que haja um custo de desempenho de compilação, pois o compilador precisa inferir o tipo, embora isso provavelmente seja insignificante.
fonte
Se o compilador puder fazer inferências automáticas de tipo, não haverá nenhum problema com o desempenho. Ambos irão gerar o mesmo código
no entanto, se você estiver construindo o tipo dinamicamente (LINQ ...), então
var
é sua única pergunta e há outro mecanismo para comparar, a fim de dizer qual é a penalidade.fonte
Eu sempre uso a palavra var em artigos da web ou orienta escritos.
A largura do editor de texto do artigo online é pequena.
Se eu escrever isso:
Você verá que o texto do código pré renderizado acima é muito longo e sai da caixa; ele fica oculto. O leitor precisa rolar para a direita para ver a sintaxe completa.
É por isso que eu sempre uso a palavra-chave var nos escritos de artigos da web.
Todo o código pré renderizado se encaixa na tela.
Na prática, para declarar objetos, raramente uso var, confio no intellisense para declarar objetos mais rapidamente.
Exemplo:
Mas, para retornar objetos de um método, uso var para escrever código mais rapidamente.
Exemplo:
fonte
"var" é uma daquelas coisas que as pessoas amam ou odeiam (como regiões). Embora, diferentemente das regiões, var seja absolutamente necessário ao criar classes anônimas.
Para mim, var faz sentido quando você está atualizando um objeto diretamente como:
Dito isto, você pode facilmente fazer:
Dictionary<string, string> dict =
O novo e o intellisense preencherão o resto para você aqui.Se você deseja trabalhar apenas com uma interface específica, não poderá usar var, a menos que o método que você está chamando retorne a interface diretamente.
O compartilhador parece estar do lado de usar "var" por toda parte, o que pode levar mais pessoas a fazer dessa maneira. Mas eu meio que concordo que é mais difícil ler se você está chamando um método e não é óbvio o que está sendo retornado pelo nome.
O var não reduz a velocidade das coisas, mas há uma ressalva sobre isso que muitas pessoas não pensam. Se você fizer
var result = SomeMethod();
isso, o código a seguir espera algum tipo de resultado, onde você chamaria vários métodos ou propriedades ou qualquer outra coisa. Se vocêSomeMethod()
mudou sua definição para outro tipo, mas ainda cumpriu o contrato que o outro código esperava, você acabou de criar um bug muito desagradável (se não houver testes de unidade / integração, é claro).fonte
Depende da situação, se você tentar usar, este código abaixo.
A expressão é convertida em "OBJECT" e diminui muito o desempenho, mas é um problema isolado.
CÓDIGO:
Resultados acima com ILSPY.
Se você deseja executar este código, use o código abaixo e obtenha a diferença de tempos.
Saudações
fonte