Jesús Bosch

XNA, programación gráfica y desarrollo de videojuegos por un Microsoft Student Partner

[C#] ¿Qué le pasa a todo el mundo? Las variables de tipo implícito no molaaan

Hoy hago un descanso de XNA para hablar de C# en general. Este lenguaje me gustaba sobre VB.NET por su "rudeza" en cuanto a la especificación de tipos y conversiones entre ellos se refiere, con un control de tipos fuerte y a prueba de "manazas", descartando muchos posibles errores humanos. El compilador actuaba como filtro de muchos errores que en otros lenguajes nos encontraríamos en tiempo de ejecución, y no en tiempo de compilación. Vamos, que si no codificabas bien no compilaba de ninguna de las maneras.

Pero en .Net 3.0 álguien decidió introducir "var" a C#, no se si para dar sentido a LINQ y los tipos anónimos, no se si para seguir tendencias, o no se si para hacerme la vida más difícil. Pues bien, gracias a esa decisión tenemos la suerte de podernos encontrar en C# con errores que bien podrían ser típicos de VB.NET, como por ejemplo esta conversión de tipos, que me ha petado en la cara al ejecutar un código hecho por un buen compañero (con su mejor intención por supuesto). Gracias Dios Microsoft por introducir el var en C#!

Si bueno, el var tiene sus ventajas, y supongo que será cuestión de gustos usarlo, pero yo os lo regalo para vosotros :-)

 

PD: Ojalá álguien me haga cambiar de opinión ofreciéndome una solución a este tipo de problemas de conversión de tipos en tiempo de ejecución!

Posted: 18/8/2010 8:00 por Jesús Bosch | con 15 comment(s)
Comparte este post:

Comentarios

Miemblogs ha opinado:

Hoy hago un descanso de XNA para hablar de C# en general. Este lenguaje me gustaba sobre VB.NET por su

# August 18, 2010 8:47 AM

r2d2rigo ha opinado:

Para que no te vaya petando puedes usar el "is":

if (miVar is MiTipo)

"is" devuelve null si no lo cumple, y el objeto casteado si lo es.

# August 18, 2010 10:33 AM

Eduard Tomàs i Avellana ha opinado:

MMMmm...

Veamos, var NO tiene nada que ver con "conversiones de tipo en tiempo de ejecución". Var no es variant, el var de c# no es el var de javascript, y C#3 no es un lenguage dinámico para nada.

Var simplemente declara una variable cuyo tipo es el tipo de la expresión que se le asigna EN TIEMPO DE COMPILACIÓN. Pero la variable será de un tipo (int, float, string, Object o MiClase) y se le aplicarán todas las conversiones implícitas, explícitas y restricciones que se apliquen a dicho tipo.

Si tienes una ArrayList que contiene objetos de tipo FooClass y haces

var a = miArrayList[0];

a será de tipo Object porque ArrayList declara que devuelve Object. Ni más ni menos. No hay conversiones, no hay castings, no hay nada de nada!

Si crees que var se resuelve en tiempo de ejecución, o bien crees que te va a realizar conversiones entre tipos, es cuando tendrás problemas.

Var no es dynamic ni se le parece... por asomo!

Un saludo!

# August 18, 2010 1:27 PM

Jesús Bosch ha opinado:

Gracias por los comentarios crack. Lo que no acabo de entender es que, si la resolución se hace en tiempo de compilación, porqué no da un error y lo da en ejecución?

# August 18, 2010 1:36 PM

El Bruno ha opinado:

Como bien dice @Eduard, el var es precompilado, así que si te da errores en tiempo de ejecución, pues la cosa es chunga :D (aunque son de las que nos gustan). Yo tiraría de Reflector para que ver que hay en las tripas del código.

El gran peligro de un ejemplo como el de tu código es "dynamic", donde si podemos encontrarnos cualquier cosa en tiempo de ejecución.

Yo que estuve un tiempito en contra del VAR, debo decir que es una ayuda fabulosa no solo para ahorrarnos declaraciones sino para ayudarnos a escribir código más "entendible".

Por ejemplo:

var x = cars.DoSomething();

no te acerca a saber que sorcho hace la funcion. Pero en cambio

var car = cars.GetLightingMcqueen();

ya te deja una idea más clara

Salu2

# August 18, 2010 2:16 PM

pregunton cojonero ha opinado:

Buena pregunta, a ver si se sabe la causa, sería intrigante entonces.

# August 18, 2010 2:26 PM

Jesús Bosch ha opinado:

a mi me da que Microsoft nos ha engañado y por dentro hay un variant de toda la vida xD

Bruno, enserio crees que esto:

var light = cars.GetLight();

es más entendible que esto?

Light light = cars.GetLight();

no se... igual soy de esos que se hacen viejos y se quedan con lo antiguo... pero no le veo la ventaja la verdad...

# August 18, 2010 2:29 PM

Zpektrum ha opinado:

Tal como yo lo veo, el 'var' es como una vuelta de tuerca más en el uso de los tipos genéricos: ya no es necesario que especifiques el tipo de dato en el código, sino que el compilador (mejor dicho el jitter) se lo "imagina".

# August 18, 2010 5:53 PM

Facundo ha opinado:

Como bien han apuntado "var" no es el "var" de JavaScript y en tiempo de compilación se realiza comprobación de tipos. Desconozco porqué ha petado el código que pones pero seguro que no se debe a un problema de casting.

# August 18, 2010 6:03 PM

Eduard Tomàs i Avellana ha opinado:

@Jesus

Estaría bien saber que error da exactamente en tiempo de ejecución, porque no puede (o no debería :P) ser debido al uso de var.

Sobre tu ejemplo, entre

var light = cars.GetLight();

y

Light light = cars.GetLight();

De hecho hay gente que opina que usar var de este modo es una mala praxis (puesto que me obliga a mirar GetLight para saber que devuelve). Yo raras veces lo uso en este contexto.

En cambio lo que si hago es:

var foo = new Light();

Aquí es evidente que foo es una Light.

Var está pensado para soportar tipos anónimos por un lado (si no tienes nombre de tipo como vas a declarar la variable sin var) y por otro lado para soportar métodos que devuelve interfaces/clases genéricas donde el tipo genérico nos es desconocido (que es lo que hace LINQ).

Si comentas el error que te da y la firma del método que se llama igual te podemos ayudar más! ;-)

Un abrazo!

# August 18, 2010 9:36 PM

Jesús Bosch ha opinado:

pues a mi me da una invalidcastexception que no veas...

PD: Si es una mala práxis todo el código que hemos hecho hasta 2.0 es una guarrada? :-P

que no que no, que no me convencéis tan facilmenteeeee

# August 18, 2010 10:33 PM

Jesús Bosch ha opinado:

vale, después de hablar con el compañero que escribió el código me ha convencido. El error viene de una conversión que igualmente se produciría sin el "var". Por lo tanto retiro lo dicho y reconozco que tendré que comenzar a usarlo un día de estos :-P

Gracias a todos por los comentarios!

# August 19, 2010 9:50 AM

Eduard Tomàs i Avellana ha opinado:

EEhh!!

Que lo que se puede considerar mala praxis es usar

var light = GetLight();

en lugar de

Light light = GetLight();

No al revés!!!!! :P

Y si ahora que var no tiene la culpa sigues sin convencerte, ya sólo que me quedan las cervezas para ello... :P

Un saludo!

# August 19, 2010 10:01 AM

Luis Guerrero ha opinado:

Lo único que mola de var es que te permite que cuando estes usando Linq no tengas que acordarte de que tipo exactamente devuelve ya que todo esta basado en interfaces. Lo bueno que tiene var es que no lo puedes definir sin inicializar.

Es mejor escribir var query = from p in item ...

que IEnumable<IGrouping<T>> query = from p in intem

Saludos.

# August 19, 2010 10:08 AM

josejuan ha opinado:

'var' mola, pero no 'var' en sí, sino el porqué está 'var' en C#.

Mirar programación funcional... os puede ahorrar escribir unas cuantas líneas (y de paso, tener mucho menos código).

# October 5, 2010 12:53 PM