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!
Hoy hago un descanso de XNA para hablar de C# en general. Este lenguaje me gustaba sobre VB.NET por su
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.
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!
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?
Como bien dice @Eduard, el var es precompilado, así que si te da errores en tiempo de ejecución, pues la cosa es chunga 😀 (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
Buena pregunta, a ver si se sabe la causa, sería intrigante entonces.
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…
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».
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.
@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!
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? 😛
que no que no, que no me convencéis tan facilmenteeeee
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 😛
Gracias a todos por los comentarios!
EEhh!!
Que lo que se puede considerar mala praxis es usar
var light = GetLight();
en lugar de
Light light = GetLight();
No al revés!!!!! 😛
Y si ahora que var no tiene la culpa sigues sin convencerte, ya sólo que me quedan las cervezas para ello… 😛
Un saludo!
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> query = from p in intem
Saludos.
‘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).