c# - example - ¿Cuál es el punto de la palabra clave var?
remarks c# (8)
La palabra clave var elimina la necesidad de una declaración de tipo explícita y he leído con interés la discusión SO de cuándo podría ser apropiado.
También he leído acerca de (pero no usado) Boo, que parece llevar las cosas un paso más allá al hacer que sea opcional declarar una variable local . Con Boo, tanto el tipo como la declaración pueden ser implícitos.
Lo que me lleva a preguntarme, ¿por qué los diseñadores de lenguaje de C # se molestaron en incluir una palabra clave var?
Actualización : Sí, var admite tipos Anónimos, pero los tipos anónimos por sí mismos no necesitan la palabra clave var ...
var anon = new { Name = "Terry", Age = 34 };
versus
anon = new { Name = "Terry", Age = 34 };
Creo que var (y varias otras palabras clave nuevas) se agregaron específicamente para admitir Linq.
var es la palabra clave utilizada para crear un tipo anónimo; consulte http://msdn.microsoft.com/en-us/library/bb397696.aspx
Los tipos anónimos se pueden usar en otros lugares además de Linq.
var es muy útil para Linq. De hecho, según un autor experto, " sin ''var'', LINQ se vuelve demasiado doloroso de usar " .
En su pregunta, var
agrega valor al código diciéndole al compilador que la palabra anon
ahora es legal para usar en cualquier lugar donde espere ver un elemento del tipo implícito en la tarea. Exigir la introducción de nombres al compilador de esta manera permite al compilador rechazar cosas que no se han indicado explícitamente, y así detectar ciertos tipos de errores en tiempo de compilación para que no exploten en el tiempo de ejecución.
Por ejemplo, en la sección de actualización de su pregunta, preguntó acerca de este fragmento:
anon = new { Name = "Terry", Age = 34 };
El problema de permitirlo de esta manera es que convierte cualquier cosa en el lado izquierdo de cualquier asignación donde el nombre no existía previamente en una declaración de variable, incluso si es realmente un error tipográfico. Si más tarde en el programa asigna algo más a anon y luego aún más en referencia al nuevo valor, pero la sentencia del medio tiene un error tipográfico, tiene un problema que no se mostrará hasta el tiempo de ejecución.
Tu respuesta es que Boo lo hace, por lo que debe estar bien o al menos posible. Pero eso es una pista falsa. Estamos hablando de C #, no de Boo. Uno de los propósitos de C # es tener un lenguaje donde el compilador pueda detectar tantos errores como sea posible. Boo también quiere hacer eso, pero también quiere ser más parecido a Python. Por lo tanto, sacrifica parte (no todos) de la seguridad en tiempo de compilación de C # a cambio de la sintaxis tipo pitón.
Entiendo la necesidad de var y sirve para un gran propósito. No tener palabras clave y simplemente definir variables sobre la marcha sin ningún tipo de texto es aterrador. Estás lastimando al próximo chico que tiene que mantener tu código o a ti mismo si necesitas volver a trabajar el código que no has tocado en un año. No estoy seguro de que sea una puerta que debería abrirse en C # y espero que no sea así porque la var ya está causando problemas de legibilidad cuando se usa en exceso cuando no es necesario.
Casi todos los ejemplos de .net 3.5 que estoy viendo últimamente tienen todas las variables definidas con var.
El argumento que hago es que realmente sacrifica la legibilidad por el simple hecho de guardar las pulsaciones de teclas cuando se usa demasiado. Por ejemplo:
// What myVar is, is obvious
SomeObject myVar = new SomeObject();
// What myVar is, is obvious here as well
var myVar = new SomeObject();
El problema que veo es que la gente lo usa en todas partes ... por ejemplo:
// WTF is var without really knowing what GetData() returns?
// Now the var shortcut is making me look somewhere else when this should
// just be readable!
var myVar = GetData();
// If the developer would have just done it explicitly it would actually
// be easily readable.
SomeObject myVar = GetData();
Entonces, el siguiente argumento será, solo nombra la función mejor ...
var weight = GetExactWeightOfTheBrownYakInKilograms();
Todavía no sé lo que está volviendo. ¿Es un objeto int, decimal, flotante, de peso, qué? Todavía tengo que perder el tiempo buscándolo ... necesito la muleta intellisense para salvar el día de mi programación perezosa. Tal vez incluya el tipo de devolución en el nombre de la función. Buena idea, ahora el uso de var no nos ha salvado nada, excepto que todas mis funciones tienen nombres realmente largos.
Creo que la gente acaba de usar var y está llevando a la programación perezosa que a su vez lleva a un código más difícil de leer. Cada vez que escribe la palabra clave var, debe tener una buena razón para usarla en lugar de ser explícita.
Esto es un poco subjetivo, pero creo que diseñar C # 3.0 para que tenga la palabra clave "var" para las variables tipadas implícitamente en lugar de ninguna palabra clave hace que el código sea más legible. Por ejemplo, el primer bloque de código a continuación es más legible que el segundo:
Obvio donde se declara la variable:
var myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;
No es obvio dónde se declara la variable:
myVariable = SomeCodeToSetVariableHere;
myVariable = SomeOtherCodeTOSetVariable;
Estos son ejemplos demasiado simplistas. Creo que puedes ver a dónde va esto. En situaciones complejas, sería bueno poder encontrar el lugar donde realmente se define una variable.
Para tipos anónimos, que, entre otras cosas, son compatibles con LINQ.
Sin la palabra clave var, se puede crear accidentalmente una nueva variable cuando en realidad se pretendía usar una variable ya existente. p.ej
name = "fred";
...
Name = "barney"; // whoops! we meant to reuse name
descargo de responsabilidad: mis ejemplos son Java porque eso es lo que sé, pero los conceptos deben ser idénticos.
Elegí la respuesta que creo que es crítica (es muy fácil crear accidentalmente una nueva variable).
bill=5;
bi11=bill+5
¿Cuál es el valor de la factura?
Dicho esto, a veces me resulta irritante escribir:
DataOutputStream ds=new DataOutputStream();
Parece redundante, pero sinceramente no hay nada realmente malo con eso. Ya no tarda más en escribirlo dos veces, y es extremadamente útil. Lo que toma tiempo es cuando tienes preguntas, cuando no estás seguro de cómo usar alguna API. Si realmente te molesta escribir la declaración de ese tipo dos veces, entonces ¿por qué estás perdiendo el tiempo aquí? Desde que comenzó a leer esto, pudo haber tipeado 30 o 40 declaraciones, suficientes para cada declaración que necesitará durante las próximas dos semanas.
Supongo que estoy diciendo que aunque entiendo el estrés emocional que puede causar la repetición de uno mismo, la consistencia, la claridad y la capacidad de hacer herramientas más inteligentes lo hacen BIEN valer la pena.
Una cosa más, la mayoría de las veces el código no debería ser como mi ejemplo anterior. Lo que deberías estar haciendo es esto:
DataOutput ds=new DataOutputStream();
Esto oculta inmediatamente el hecho de que está utilizando una clase concreta en una plantilla. Esa plantilla debe poder hacer todas las operaciones que necesita en su clase. Más tarde, si desea reemplazar ds con algún otro tipo de flujo de salida, simplemente cambiar esa única línea lo arreglará. Si usaba las funciones que no estaban disponibles para DataOutput al convertirlas a DataOutputStream, el editor las resolvería fácilmente y le haría saber.
Actualización: en este caso, hay dos preguntas relacionadas: 1. ¿Por qué tengo que declarar las variables? 2. ¿De qué sirve "var" en un lenguaje que te hace declarar variables?
Las respuestas a (1) son numerosas y se pueden encontrar en otra parte para esta pregunta. Mi respuesta a (2) está debajo:
Como han dicho otros comentadores, LINQ usa esto para sus tipos anónimos. Sin embargo, LINQ es en realidad una instancia de un problema más general en el que el tipo del lado derecho de una expresión es desconocido para el programador o es extremadamente detallado. Considerar:
SomeGeneric<VeryLongTypename<NestedTypename>> thing = new
SomeGeneric<VeryLongTypename<NestedTypename>>();
Verboso y propenso a errores, ¿verdad? Entonces ahora te dejan hacer esto:
var thing = new SomeGeneric<VeryLongTypename<NestedTypename>>();
Al reducir la duplicación de información, se eliminan los errores. Tenga en cuenta que aquí no solo hay errores de tipeo: es posible que el tipo de la expresión de la izquierda sea mal escrita de tal manera que el compilador pueda emitir de forma silenciosa de izquierda a derecha, pero el elenco realmente pierde alguna propiedad del rvalue Esto es aún más importante cuando los tipos devueltos por el valor de r pueden ser desconocidos o anónimos.