Pregunta

    

Esta pregunta ya tiene una respuesta aquí:

    
            
  •              Uso de la palabra clave var en C #                                      86 respuestas                          
  •     
    

esta es una pregunta que cuando programo siempre me pregunto: qué usar cuando escribimos código:

var myFiles = Directory.GetFiles(fullPath);

o

string[] myFiles = Directory.GetFiles(fullPath);

var es nuevo y es una Variable local tipada implícitamente , por lo que solo podemos usarla localmente y tiene reglas que no pueden ser nulo, etc., pero me pregunto si tenemos alguna ventaja de usarlo " normalmente " ;.

El " normalmente " la parte dice, no en Tipos anónimos , Inicializadores de objetos y colecciones y Expresiones de consulta donde esa era la intención de usar el objeto anónimo var, entonces qué Quiero decir es ... como en el ejemplo anterior.

¿Qué piensas?

¿Fue útil?

Solución

Más allá del uso obvio de var con LINQ, también lo uso para abreviar declaraciones de variables peludas para facilitar la lectura, por ejemplo:

var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();

En general, obtengo una especie de consuelo (a falta de una palabra mejor) del tipeo estático que me hace reacio a abandonarlo. Me gusta la sensación de saber lo que estoy haciendo cuando declaro una variable. Declarar una variable no es solo decirle algo al compilador, es decirle a la persona que lee su código algo.

Déjame darte un ejemplo. Supongamos que tengo un método que devuelve un List<string>. Este código es ciertamente correcto, y creo que así es como el 90% de los desarrolladores de C # probablemente lo escribirían:

List<string> list = MyMethod();

Obviamente, ¿verdad? De hecho, aquí hay un lugar que podría usar con la misma facilidad rows.

Suficientemente cierto. Pero esta versión del código no solo declara una variable, sino que me dice lo que la persona que lo escribió tiene la intención de hacer:

IEnumerable<string> list = MyMethod();

El desarrollador que escribió ese código me dice " No voy a cambiar esta lista, ni voy a usar un índice para acceder a sus miembros. Todo lo que voy a hacer es iterar sobre él. & Quot; Esa es una gran cantidad de información para transmitir en una sola línea de código. Es algo que abandonas si usas IEnumerable<DataRow>.

Por supuesto, no lo vas a abandonar si no lo estabas usando en primer lugar. Si eres el tipo de desarrollador que escribiría esa línea de código, ya sabes que no usarías IEnumerable<T> allí.

Editar:

Acabo de releer la publicación de Jon Skeet, y esta cita de Eric Lippert me llamó la atención:

  

Los locales tipados implícitamente son solo una pequeña forma en la que puede enfatizar el cómo y, por lo tanto, enfatizar el qué.

Creo que, en muchos casos, el uso del tipeo implícito es dejar lo implícito. Está bien no detenerse en el qué. Por ejemplo, escribiré casualmente una consulta LINQ como:

var rows = from DataRow r in parentRow.GetChildRows(myRelation)
           where r.Field<bool>("Flag")
           orderby r.Field<int>("SortKey")
           select r;

Cuando leo ese código, una de las cosas que creo cuando lo leo es " <=> es un <=>. " Porque sé que lo que devuelven las consultas LINQ es <=>, y puedo ver el tipo de objeto que se selecciona allí mismo.

Ese es un caso en el que lo no se ha hecho explícito. Me ha quedado para inferir.

Ahora, en aproximadamente el 90% de los casos en que uso LINQ, esto no importa ni un poquito. Porque el 90% del tiempo, la siguiente línea de código es:

foreach (DataRow r in rows)

Pero no es difícil imaginar un código en el que sería muy útil declarar <=> como <=> - código donde se consultaban muchos tipos diferentes de objetos, no era factible colocar la declaración de consulta junto a la iteración, y sería útil poder inspeccionar <=> con IntelliSense. Y eso es qué, no cómo.

Otros consejos

Obtendrá una gran variedad de opiniones sobre esto: de " use var en todas partes " a " solo use var con tipos anónimos, donde básicamente tiene que. " Me gusta La versión de Eric Lippert sobre ella :

  

Todo el código es una abstracción. Qué es   el código es & # 8220; realmente & # 8221; hacer es   manipulando datos? ¿Números? Bits?   No. voltajes? No. Electrones? Sí, pero   entender el código a nivel de   electrones es una mala idea! El arte de   la codificación es averiguar cuál es el derecho   nivel de abstracción es para el   audiencia.

     

En un lenguaje de alto nivel hay   siempre esta tensión entre lo que el   el código lo hace (semánticamente) y CÓMO   El código lo logra. Mantenimiento   los programadores necesitan entender ambos   el qué y el cómo si & # 8217; van   tener éxito en hacer cambios.

     

El objetivo de LINQ es que   desestima masivamente el " cómo " y   enfatiza masivamente el " what " ;. Por   utilizando una comprensión de consulta, el   programador está diciendo al futuro   audiencia " Creo que deberías   ni sé ni me importa exactamente cómo esto   se está calculando el conjunto de resultados, pero usted   debe preocuparse mucho por lo que el   la semántica del conjunto resultante es. "   Hacen el código más cercano al   proceso de negocio implementado y   más lejos de los bits y electrones   que lo hacen funcionar.

     

Los locales tipados implícitamente son solo uno   pequeña forma en que puedes enfatizar   el cómo y por lo tanto enfatizar el   qué. Si eso es lo correcto   hacer en un caso particular es una   llamada de juicio. Entonces le digo a la gente que   si el conocimiento del tipo es relevante   y su elección es crucial para   operación continua del método,   entonces no use tipeo implícito.   La escritura explícita dice & Quot; Te estoy diciendo   cómo funciona esto por una razón, paga   atención " ;. La escritura implícita dice & Quot; it   no & # 8217; no importa un poco si esto   Lo es una lista o una   Cliente [], lo que importa es que es   una colección de clientes. "

Personalmente, no tiendo a usarlo si el tipo no es razonablemente obvio, donde incluyo las consultas LINQ como " razonablemente obvio " ;. Por ejemplo, no lo haría por Directory.GetFiles, ya que no es realmente obvio que eso devuelva un string[] en lugar de (digamos) un FileInfo[] (o algo completamente diferente), y eso hace una gran diferencia en lo que usted hacer más tarde.

Si hay una llamada de constructor en el lado derecho del operador de asignación, es mucho más probable que elija var: es obvio cuál será el tipo. Esto es particularmente útil con tipos genéricos complejos, p. Dictionary<string,List<int>>.

Personalmente, solo uso var en dos lugares:

  1. Con tipos anónimos, es decir. Relacionado con LINQ (donde se requiere var en algunos casos)
  2. Cuando la declaración declara y construye un tipo específico en el mismo tipo

es decir. Este es un ejemplo del punto 2:

var names = new List<String>();

Editado : Esto en respuesta a la pregunta de Jon Skeet.

La respuesta anterior fue de hecho simplificada. Básicamente, uso var donde el tipo es:

  1. Innecesario saber (aunque no tantos lugares)
  2. Imposible de saber (LINQ, tipos anónimos)
  3. Conocido de otro modo, o claro del código

En el caso de un método de fábrica, donde todo lo que necesita saber en el lugar donde escribe el código es que el objeto que recupera es un descendiente de algún tipo, y que algún tipo tiene un método de fábrica estático, entonces usaría var . Así:

var connection = DatabaseConnection.CreateFromConnectionString("...");

El ejemplo anterior es un ejemplo real de mi código. Está claro, al menos para mí y para las personas que usan este código, que conexión es un descendiente de DatabaseConnection, pero el tipo exacto no es necesario para comprender el código ni usarlo.

Probé el " use var en todas partes " estilo ... y esta es la razón por la que no continué usándolo.

  1. Legibilidad degradada a veces
  2. Limita Intellisense after =
  3. Escribiendo " var " realmente no fue mucho más corto que escribir " int " ;, " string " ;, etc., especialmente con intellisense.

Dicho esto, todavía lo uso con LINQ.

Viniendo de la tierra de la programación funcional, donde la inferencia de tipos rige el día, uso var para todos los locales siempre que sea posible.

En Visual Studio, si alguna vez se pregunta cuál es el tipo de local, todo lo que tiene que hacer es desplazarse sobre él con el mouse.

Esto post tiene algunas buenas pautas sobre cuándo usar la interfaz de tipo var o los tipos de objeto.

Tiendo a usar var en todas partes, pero mis compañeros de trabajo dijeron: para, es menos legible para nosotros. Así que ahora uso <=> solo en tipos anónimos, consultas LINQ y dónde está el constructor en el lado derecho.

Creo que es interesante notar cómo esto se maneja generalmente en Haskell. Gracias al Curry-Howard isomorphism , el tipo (más general) de cualquier expresión en Se puede inferir Haskell y, por lo tanto, las declaraciones de tipo no se requieren esencialmente en ninguna parte, con algunas excepciones; por ejemplo, a veces desea limitar deliberadamente el tipo a algo más específico de lo que se deduciría.

Por supuesto, lo que se requiere y lo que se recomienda no es lo mismo; En la práctica, la convención parece ser que las definiciones de nivel superior siempre tienen declaraciones de tipo, mientras que las definiciones localizadas tienen las declaraciones de tipo omitidas. Esto parece lograr un buen equilibrio entre lo explícito para la legibilidad de la definición como un todo, en contraste con la brevedad para la legibilidad de la & Quot; helper & Quot; o " temporal " definiciones Si entiendo correctamente, no puede usar var para & Quot; nivel superior & Quot; definiciones (como un método o función global) en primer lugar, así que supongo que esto se traduce en " use int donde sea que pueda " en el mundo C #. Por supuesto, escribiendo & Quot; <=> & Quot; es el mismo número de pulsaciones de teclas que " <=> " ;, pero la mayoría de los ejemplos serán más largos que eso.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top