Menu

Declarando variables: Dynamic, Var y Object

Abril 13, 2013 - .NET

Normalmente cuando declaramos una variable en nuestra aplicación sea web o de escritorio, lo hacemos declarando su tipo de datos especifico, por ejemplo:

int num;

string mystring;

Pero en ciertas ocasiones, si trabajamos con reflection, LINQ u otras tecnologías no es posible saber que tipo de dato sera el que retorne cierto método, para esto existen los tipos de dato Dynamic, Var y Object. Echemos un vistazo a cada una de estas.

 

Requisitos

Manos a la obra!

 

Variables tipo object

Object es el tipo de dato raíz de todo el esquema de objectos del .NET Framework y todo lo que no sea un puntero deriva de esta clase (Sí, no todo deriva de Object, más info en este post de Eric Lippert), esta en el .NET Framework desde su versión 1.1 por tanto cuasi cualquier tipo de dato puede ser convertible a Object, por ejemplo:

Object myObject;

myObject = 10;

Console.WriteLine(myObject.GetType().ToString());

Console.ReadKey();

image

Si es de tipo Int32 podemos entonces hacer operaciones con el no?

Object myObject;

myObject = 10;

myObject = myObject + 10;

Console.WriteLine(myObject.GetType().ToString());

Console.ReadKey();

image

Pero si el tipo de datos en Int32 porque no podemos aplicarle el operador “+” que este caso representa un simple suma??, la respuesta es que el tipo de datos estático declarado es Object, por tanto para realizar la operacion debemos de hacer una conversion explicita al tipo de datos que necesitamos:

Object myObject;

myObject = 10;

myObject = (int)myObject + 10;

Console.WriteLine(myObject.GetType().ToString());

Console.ReadKey();

image

Ahora la operación se realizo sin problemas con el casteo explicito. Pero que sucede si ahora le asignamos a la variable myObject un tipo de dato diferente?

Object myObject;

myObject = 10;

myObject = (int)myObject + 10;

myObject = "Hello world";

Console.WriteLine(myObject.GetType().ToString());

Console.ReadKey();

image

Ahora el tipo de datos es string!!! y si intentamos hacer una operacion de suma sobre él?

Object myObject;

myObject = 10;

myObject = (int)myObject + 10;

myObject = "Hello world";

myObject = (int)myObject + 10;

Console.WriteLine(myObject.GetType().ToString());

Console.ReadKey();

 

image

Se lanza una excepción como esperaba ya que estoy tratando de sumar un string con un entero, sin embargo el compilador no nos advirtió de la posible excepción ya que como dije antes el tipo de dato estático declarado es Object, que internamente se guarde un Int32 o String es otra historia, así que el compilador no sabe que tipo de dato tiene en su interior la variable object.

 

Variables tipo var

Var es una palabra reservada introducida en la versión 3.0 del .NET Framework, básicamente su uso se da mas que todo en consultas tipo LINQ para inferir el tipo de dato retornado por la consulta, sin embargo puede ser utilizable en cualquier ámbito. Veamos un ejemplo:

var myVar = 10;

myVar = myVar + 10;

Console.WriteLine(myVar.GetType().ToString());

Console.ReadKey();

image

Podemos ver que pudimos realizar una operacion de suma sin necesidad de hacer un casteo explicito (De hecho tampoco el compilador hizo un casteo implícito), además se nos muestra claramente el tipo de datos que hemos asignado en la declaración de la variable. Ahora veamos que pasa si le asignamos un tipo de dato deiferente.

var myVar = 10;

myVar = myVar + 10;

myVar = "Hello world";

Console.WriteLine(myVar.GetType().ToString());

Console.ReadKey();

image

El compilador nos advierte que no podemos hacer la asignación, esto nos demuestra que aunque hayamos declarado la variable como Var, internamente se infiere el tipo de dato correcto, esta es la razón por la cual al declarar la variable debemos inicializarla, el compilador necesita saber que tipo de dato le asignamos para declarar la variable como ese tipo de dato especifico.

Usar Var tiene ciertas limitantes:

Variables tipo dynamic

Dynamic se introdujo en .NET Framework 4.0 para mejorar la interoperabilidad con lenguajes dinámicos y frameworks, pero tal como con Var también puede ser usado en otros ámbitos, veamos un ejemplo:

dynamic myDyn;

myDyn = 10;

myDyn = myDyn + 10;

Console.WriteLine(myDyn.GetType().ToString());

Console.ReadKey();

image

Al declarar la variable como dynamic no necesariamente tenemos que inicializarla, y además como podemos ver se pueden realizar operaciones sobre la variable sin necesidad de una conversión explícita. Veamos que sucede cuando le asignamos otro tipo de dato:

dynamic myDyn;

myDyn = 10;

myDyn = myDyn + 10;

Console.WriteLine(myDyn.GetType().ToString());

myDyn = "Hello world";

Console.WriteLine(myDyn.GetType().ToString());

Console.ReadKey();

image

La misma variable es de dos tipos de datos distintos, esto es que esta declarada estáticamente como un tipo de datos dinámico (WTF?), lo que sucede realmente es que cuando una variable esta declarada con dynamic el compilador no realiza chequeo con esa variable en especifico, así el tipo de dato es determinado en tiempo de ejecución, lo cual permite que realicemos operaciones sin que el compilador nos arroje error y esa es la principal diferencia con Object. Esto supone como en todo ventajas y desventajas, ventajas al tener que codificar menos pero desventaja porque perdemos una de las caracteristicas mas fuertes del .NET Framework, el tipado estático o tipado fuerte.

Al contrario de Var, dynamic si puede ser utilizado como tipo de retorno de un método y también para declarar variables en una clase.

Conclusión

El .NET Framework ha evolucionado en muchos aspectos, permitiéndonos flexibilidad a la hora de codificar, en el caso especifico de la declaración de variables recomiendo siempre que sea posible declarar variables con su tipo especifico o lo que es igual con var, sin embargo declarar todo como var tiene sus riesgo y es que en un mismo ámbito puede que debamos escoger bien el nombre de las variables, por lo demás actúa exactamente igual a declarar una variable con su tipo.

Happy coding Sonrisa!

Etiquetas: , ,

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *