Anteriormente, hice una pregunta sobre por qué veo tantos ejemplos que usan la var
palabra clave y obtuve la respuesta de que, aunque solo es necesario para los tipos anónimos, se usa para hacer que la escritura de código sea 'más rápida' / más fácil y 'solo porque'.
Siguiendo este enlace ("C # 3.0 - Var no es un objeto") , vi que var
se compila en el tipo correcto en el IL (lo verá sobre el artículo a mitad de camino).
Mi pregunta es ¿cuánto más, si es que hay alguno, usa el código IL usando la var
palabra clave, y estaría incluso cerca de tener un nivel medible en el rendimiento del código si se usara en todas partes?
c#
performance
variables
var
Jeff Keslinke
fuente
fuente
var
definitivamente funcionan con "Buscar todas las referencias" en Visual Studio 2019, por lo que si alguna vez se rompió, se ha solucionado. Pero puedo confirmar que funciona desde Visual Studio 2012, así que no estoy seguro de por qué afirmas que no funcionó.var
no se considerará una referenciaX
cuando uses "Buscar todas las referencias" enX
. Curiosamente, si usa "Buscar todas las referencias"var
en esa declaración, le mostrará referencias aX
(aunque todavía no incluirá lavar
declaración). Además, cuando el cursor está activadovar
, resaltará todas las instancias delX
mismo documento (y viceversa).Respuestas:
No hay un código IL adicional para la
var
palabra clave: la IL resultante debe ser idéntica para los tipos no anónimos. Si el compilador no puede crear esa IL porque no puede determinar qué tipo de intención tenía de usar, obtendrá un error del compilador.El único truco es que
var
inferirá un tipo exacto en el que puede haber elegido una interfaz o un tipo principal si tuviera que configurar el tipo manualmente.Actualización 8 años después
Necesito actualizar esto ya que mi comprensión ha cambiado. Ahora creo que es posible
var
afectar el rendimiento en la situación en la que un método devuelve una interfaz, pero habría utilizado un tipo exacto. Por ejemplo, si tiene este método:Considere estas tres líneas de código para llamar al método:
Los tres compilan y ejecutan como se esperaba. Sin embargo, las dos primeras líneas no son exactamente iguales, y la tercera línea coincidirá con la segunda, en lugar de la primera. Porque la firma de
Foo()
es devolver unIList<int>
, así es como el compilador construirá labar3
variable.Desde el punto de vista del rendimiento, en su mayoría no lo notará. Sin embargo, hay situaciones en las que el rendimiento de la tercera línea puede no ser tan rápido como el rendimiento de la primera . A medida que continúe usando el
bar3
variable, es posible que el compilador no pueda enviar llamadas a métodos de la misma manera.Tenga en cuenta que es posible (incluso probable) que el jitter pueda borrar esta diferencia, pero no está garantizado. En general, aún debe considerar
var
que no es un factor en términos de rendimiento. Ciertamente no es como usar unadynamic
variable. Pero decir que nunca hace la diferencia puede ser exagerado.fuente
var i = 42;
(el tipo de infers es int) NO es idéntico along i = 42;
. Entonces, en algunos casos, puede estar haciendo suposiciones incorrectas sobre la inferencia de tipos. Esto podría causar errores de tiempo de ejecución delusive / edge case si el valor no se ajusta. Por esa razón, aún puede ser una buena idea ser explícito cuando el valor no tiene un tipo explícito. Entonces, por ejemplo,var x = new List<List<Dictionary<int, string>()>()>()
sería aceptable, perovar x = 42
es algo ambiguo y debe escribirse comoint x = 42
. Pero a cada uno lo suyo ...var x = 42;
no es ambiguo. Los literales enteros son del tipoint
. Si quieres un largo literal, escribevar x = 42L;
.Foo
devuelve aList
, en lugar de anIList
, las tres líneas se compilarían, pero la tercera línea se comportaría como la primera línea , no como la segunda.Como dice Joel, el compilador calcula en tiempo de compilación qué tipo de var debería ser, efectivamente, es solo un truco que realiza el compilador para guardar las pulsaciones de teclas, por ejemplo
es reemplazado por
por el compilador antes de que se genere cualquier IL. La IL generada será exactamente la misma que si hubiera escrito una cadena.
fuente
Como nadie ha mencionado el reflector todavía ...
Si compila el siguiente código C #:
Luego use reflector en él, obtendrá:
¡Entonces la respuesta es claramente que no hay éxito en el tiempo de ejecución!
fuente
Para el siguiente método:
La salida IL es esta:
fuente
El compilador de C # infiere el tipo verdadero de la
var
variable en tiempo de compilación. No hay diferencia en la IL generada.fuente
Entonces, para ser claros, es un estilo de codificación perezosa. Prefiero los tipos nativos, dada la opción; Tomaré ese poco de "ruido" adicional para asegurarme de que estoy escribiendo y leyendo exactamente lo que creo que estoy en el momento del código / depuración. * encogerse de hombros *
fuente
var
afecta el rendimiento en absoluto; solo estás expresando tu opinión sobre si las personas deberían usarlo.int
porque no puede convertir automáticamentefloat
, pero eso es exactamente lo mismo que sucedería si lo usara explícitamenteint
y luego lo cambiarafloat
. En cualquier caso, su respuesta aún no responde a la pregunta "¿el usovar
afecta el rendimiento?" (particularmente en términos de IL generada)No creo que hayas entendido bien lo que lees. Si se compila con el tipo correcto, entonces no es ninguna diferencia. Cuando hago esto:
El compilador sabe que es un int y genera código como si hubiera escrito
Como dice la publicación a la que se vinculó, se compila al mismo tipo. No es una verificación de tiempo de ejecución ni ninguna otra cosa que requiera código adicional. El compilador solo descubre cuál debe ser el tipo y lo usa.
fuente
No hay costo de rendimiento de tiempo de ejecución por usar var. Sin embargo, sospecharía que hay un costo de rendimiento de compilación ya que el compilador necesita inferir el tipo, aunque probablemente sea insignificante.
fuente
Si el compilador puede hacer inferencias de tipo automáticas, entonces no habrá ningún problema con el rendimiento. Ambos generarán el mismo código
sin embargo, si está construyendo el tipo dinámicamente (LINQ ...), entonces
var
es su única pregunta y hay otro mecanismo con el que comparar para decir cuál es la penalización.fuente
Siempre uso la palabra var en artículos web o escritos de guías.
El ancho del editor de texto del artículo en línea es pequeño.
Si escribo esto:
Verá que el texto del código anterior representado anteriormente es demasiado largo y sale de la caja, se oculta. El lector debe desplazarse hacia la derecha para ver la sintaxis completa.
Es por eso que siempre uso la palabra clave var en los escritos de artículos web.
Todo el pre código prestado solo cabe dentro de la pantalla.
En la práctica, para declarar objetos, rara vez uso var, confío en intellisense para declarar objetos más rápido.
Ejemplo:
Pero, para devolver el objeto de un método, uso var para escribir código más rápido.
Ejemplo:
fuente
"var" es una de esas cosas que la gente ama u odia (como las regiones). Sin embargo, a diferencia de las regiones, var es absolutamente necesario al crear clases anónimas.
Para mí, var tiene sentido cuando estás renovando un objeto directamente como:
Dicho esto, puedes hacer fácilmente:
Dictionary<string, string> dict =
nuevo e intellisense completará el resto aquí.Si solo desea trabajar con una interfaz específica, no puede usar var a menos que el método al que llama devuelva la interfaz directamente.
Resharper parece estar del lado de usar "var" en todas partes, lo que puede empujar a más personas a hacerlo de esa manera. Pero estoy de acuerdo en que es más difícil de leer si está llamando a un método y no es obvio lo que devuelve el nombre.
var en sí no ralentiza las cosas, pero hay una advertencia sobre esto que no mucha gente piensa. Si lo hace
var result = SomeMethod();
, el código después de eso espera algún tipo de resultado donde llamaría a varios métodos o propiedades o lo que sea. SiSomeMethod()
cambió su definición a otro tipo pero aún cumplió con el contrato que esperaba el otro código, acaba de crear un error realmente desagradable (por supuesto, si no hay pruebas de unidad / integración).fuente
Depende de la situación, si intentas usar este código a continuación.
La expresión se convierte en "OBJETO" y disminuye mucho el rendimiento, pero es un problema aislado.
CÓDIGO:
Resultados anteriores con ILSPY.
Si desea ejecutar este código, use el siguiente código y obtenga la diferencia de veces.
Saludos
fuente