Saltar al contenido

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript... y lo que venga ;)

17 años online

el blog de José M. Aguilar

Inicio El autor Contactar

Artículos, tutoriales, trucos, curiosidades, reflexiones y links sobre programación web
ASP.NET Core, MVC, Blazor, SignalR, Entity Framework, C#, Azure, Javascript...

¡Microsoft MVP!
lunes, 10 de diciembre de 2007
Hasta la versión 3.0 de C#, la declaración de una variable se debía realizar indicando su tipo de datos antes del identificador elegido para la misma. También era muy frecuente definir en ese mismo momento su valor inicial, siguiendo un patrón similar al siguiente:
  string s = "cadena";
Sin embargo, la declaración anterior es redundante. Si la constante "cadena" es un string, ¿por qué hace falta indicar que la variable s también lo es?

Las variables locales implícitamente tipadas permiten obviar en su declaración el tipo que tendrán, dejando al compilador la tarea de averiguar cuál será en función de las variables o constantes que se usen al inicializarlo. Por tanto, será posible escribir código como:
  var x = XmlDateTimeSerializationMode.Local;
Y será equivalente a:

XmlDateTimeSerializationMode x = XmlDateTimeSerializationMode.Local;
 
Creo que no hace falta decir cuál de ellas es más cómoda a la hora de programar, ¿no? Simplemente hemos indicado con la palabra var que preferimos que sea el compilador el que haga el trabajo sucio.

Otro contexto donde este tipo de variables pueden facilitarnos la vida de forma frecuente es en los bucles for, foreach y bloques using:
  // Un ejemplo de bucle...
var chars = "Saludicos".ToCharArray();
foreach (var ch in chars)
{
Console.Write(ch); // ch es char
}

// Y ahora un bloque using...
using (var ctx = new AppContext())
{
// usamos ctx, que es de tipo AppContext
}
 
También es importante la existencia de esta nueva forma de declaración para posibilitar la creación de objetos de tipo anónimo, es decir, aquellos cuya especificación de clase se crea en el mismo momento de su definición. Por tanto, una declaración como la siguiente será válida:
  var x = new { Nombre = "Juan", Edad = 23 };
Para no desviarme del objetivo de este post, otro día hablaremos más detenidamente de las clases anónimas, aunque adelantaré que una vez compilado el código anterior el resultado será algo parecido al siguiente:

class __Anonymous1
{
private string nombre ;
private int edad ;
public string Nombre { get { return nombre ; } }
public int Edad { get { return edad ; } }
public __Anonymous1(string nombre, int edad)
{
this.nombre = nombre;
this.edad = edad;
}
}
...
__Anonymous1 x = new __Anonymous1("Juan", 23);

 
Existen ciertas reglas de obligado cumplimiento para usar variables locales implícitamente tipadas:
  • La declaración debe incluir un valor de inicialización. En otras palabras, no será posible usar en una línea var i;, puesto que el compilador no podría inferir el tipo en este momento.
  • El valor de inicialización debe ser una expresión evaluable como clase en tiempo de compilación. Expresamente prohibido el valor null, es decir, nada de var n = null;, puesto que el compilador no sabría de qué tipo se trata; eso sí, si fuera necesario, podría forzarse un casting var str = null as string;.
  • La declaración no puede incluir más de una variable. Una línea como var i = 1, s = "hola"; generará un error en compilación.
  • El inicializador no puede referirse a la propia variable declarada, obviamente.
  • Sólo pueden utilizarse como variables locales en bloques de código, en bucles for y foreach y como recurso de un bloque using.

Por último, me gustaría añadir un par de detalles que considero interesantes.

Seguimos teniendo Intellisense...Primero, el hecho de utilizar la palabra "var" y no indicar de forma explícita el tipo puede hacernos pensar que estamos utilizando tipado dinámico en tiempo de ejecución, como lo hacemos con Javascript, sin embargo esto no es así. Como he comentado anteriormente, el compilador toma el tipo del lado derecho de la asignación de inicialización, por lo que si la variable no es inicializada se produce un error de compilación:
Implicitly-typed local variables must be initialized
(Las variables locales implícitamente tipadas deben ser inicializadas)
Por ello, un entorno como Visual Studio sabe en todo momento el tipo exacto de que se trata, y nos puede ofrecer las ayudas en la codificación, detección de errores sintáticos e intellisense, como se puede observar en la imagen.

Segundo, y muy interesante. Como ya comenté en su momento, la nueva versión de Visual Studio permite la generación de ensamblados para versiones anteriores de la plataforma, es decir, que es posible escribir código C# 3.0 y generar un ensamblado para el framework 2.0. Esto, a efectos prácticos, implica que una vez demos el salto definitivo a VS2008 podremos usar las variables locales de tipo implícito, así como otras novedades del lenguaje, incluso en aplicaciones diseñadas para .NET 2.0.



Publicado en: Variable Not Found.

4 Comentarios:

Anónimo dijo...

Amigo, lo que estás recomendando es una mala práxis.

Usar declaraciones implícitas genera código difícil de mantener y puede generar bugs díficiles de depurar.

josé M. Aguilar dijo...

Hola, Delroy, ante todo gracias por tu comentario.

Como todo en este mundo, esta característica puede volverse negativa si se usa sin conciencia de lo que se está haciendo realmente. Efectivamente delegar al compilador la decisión del tipo de dato a emplear en cada caso puede provocar bugs muy difíciles de detectar si no sabemos perfectamente cómo se tipará la variable.

Un ejemplo: var i = 0 no es lo mismo que var i = 0.0. El primero generará un int y el segundo un double, y esto puede provocar problemas en ejecución si no lo tenemos claro. También pueden resultar peligrosos los efectos secundarios de ciertas refactorizaciones, como cambios en el tipo de retorno de funciones utilizadas en las inicializaciones de estas variables.

Por tanto, es cierto que deben ser utilizadas con mucho ojo.

Pero en cualquier caso se trata de una característica de C# diseñada para dar soporte y sobre la que se sientan otras mejoras de peso como los tipos anónimos, o el propio Linq, por lo que su uso al menos en estos casos será obligatorio.

Ronald dijo...

ytAgrees hola amigos y como podria utilizar un var en visual c# 2005 o compatible?

José María Aguilar dijo...

Hola @Ronald.

Creo que C# 3 sólo estaba disponible desde VS2008, por lo que probablemente no puedas usar "var" en VS2005.

Saludos!