¿Por qué ReSharper quiere usar 'var' para todo?

214

Acabo de comenzar a usar ReSharper con Visual Studio (después de las muchas recomendaciones sobre SO). Para probarlo, abrí un proyecto reciente de ASP.NET MVC. Una de las primeras y más frecuentes cosas que he notado que sugiere es cambiar la mayoría / todas mis declaraciones explícitas a varcambio. Por ejemplo:

//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

y así sucesivamente, incluso con tipos simples, tales como int, bool, etc.

¿Por qué se recomienda esto? No vengo de una ciencia informática o de .NET, habiendo "caído en" el desarrollo de .NET recientemente, así que realmente me gustaría entender qué está pasando y si es beneficioso o no.

Chris
fuente
27
He estado pensando en esto por un tiempo y llegué a la conclusión de que siempre debería usar var, ¡incluso cuando el tipo no es obvio en absoluto! la razón es porque me obliga a elegir el nombre más descriptivo que se me ocurre y, en última instancia, eso hace que el código sea mucho, mucho más legible. En última instancia, también ayuda a separar la lógica de la implementación. Por supuesto, esa es solo mi opinión, espero que ayude a alguien;).
MasterMastic

Respuestas:

189

Una razón es la legibilidad mejorada. ¿Cual es mejor?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

o

var dictionary = new Dictionary<int, MyLongNamedObject>();
Mark Sherretta
fuente
260
Yo diría el primero. ¡Es más fácil ver qué está pasando!
Mongus Pong el
104
Hongo: ¿Te gusta? Te gusta Texto redundante Texto redundante? : D
Mark Simpson
73
Ser explícito es más claro en mi opinión. Usar var demasiado crea un dolor de cabeza en algunos escenarios.
user1231231412
172
Odio cuando los desarrolladores pueden utilizar varpara todo - me hacen montones y montones de revisiones de código utilizando TFS (diferenciaciones basadas en web) y hace que mi trabajo extremadamente difícil: es decir var items = GetSomeItems();vs IDataReader dr = GetSomeItems();Missing instrucción using de ambos, pero más fácil para mí para coger al utilizar IDataReadervs var.
Chris Gessler
17
Si eres un buen desarrollador que escribe un buen código y estás usando una biblioteca como Resharper, entonces no necesitas saber el tipo explícito con el que estás tratando. Al igual que cuando usa interfaces para declarar un contrato, pero no una clase concreta, var le permite decir que no le importa cuál es el "tipo" de retorno, solo le importa lo que hace, y usando variables bien nombradas, junto con con ayuda de Intelli-sense & resharper / VS (como CTRL + CLIC para navegar a la definición) obtendrá el 99% del camino. Además, el uso de var significa que no tengo que volver a escribir mi base de código si cambio el tipo de retorno de un método.
Joshua Barker
286

Lo que sugiere ReSharper es claramente el uso excesivo de la palabra clave var. Puede usarlo donde el tipo es obvio:

var obj = new SomeObject();

Si el tipo no es obvio, debería escribirlo:

SomeObject obj = DB.SomeClass.GetObject(42);
Guffa
fuente
36
Para jugar al defensor de los demonios, tal vez si el tipo no está claro en el método o en el nombre de la variable, indica un problema al nombrar más que un uso excesivo de var. Sin embargo, estoy de acuerdo en principio, var solo debe usarse cuando no elimina la claridad.
Matt Briggs
33
En este caso, preferiría usar mejores nombres de variables. Básicamente, está proponiendo que miremos hacia arriba para ver dónde se define la variable para determinar el tipo; estoy proponiendo que nombremos mejor las variables para que sepamos el propósito de la variable de manera espontánea.
Jaco Pretorius
18
@Jaco: +1, pero vale la pena mencionar que no se recomienda que la información sobre el tipo esté en un nombre de variable. Por ejemplo, la notación húngara no se considera una buena práctica.
Roman Boiko
8
Si la configuración predeterminada de ReSharper es un uso excesivo vares una cuestión de opinión, y no "claramente" una cosa u otra. Prefiero no escribir cosas que el compilador puede resolver por sí mismo. Me gusta la inferencia de tipo C #, y a menudo desearía que fuera tan buena como la inferencia de tipo F #. Si pudiera, dejaría de lado los tipos explícitos de los parámetros del método y los tipos de retorno, como es la norma en F #. No todos están de acuerdo, por supuesto.
Joel Mueller
15
@AnonymousType: todavía te falta el punto. Usted dijo que los nombres de los métodos siempre deben reflejar la intención del método, pero incluso si lo hacen, eso no significa que el nombre especifique el tipo del valor de retorno. El método para leer de un Streamobjeto, por ejemplo, se llama Read, no ReadAndReturnNumberOfBytesAsInt32.
Guffa
99

Personalmente prefiero desactivar esta sugerencia. El uso a varmenudo puede mejorar la legibilidad; pero como mencionó, a veces lo reduce (con tipos simples, o cuando el tipo resultante es oscuro ).

Prefiero elegir cuándo lo uso vary cuándo no. Pero de nuevo, solo soy yo.

Bryan Menard
fuente
11
Pensé que ReSharper estaba destinado a ser bastante inteligente; ¿No debería ser lo suficientemente inteligente como para saber cuándo el tipo resultante es obvio (por ejemplo, cualquier cosa con la nueva palabra clave) y cuándo no lo es?
DisgruntledGoat
3
Bueno, no conozco las peculiaridades de la función, pero sé que me sentí abrumado por la cantidad de sugerencias que me dio; Y lo uso con varbastante frecuencia también.
Bryan Menard
55
Descubrí que cuando siempre usas var (como sugiere resharper), te obliga a nombrar tus variables correctamente.
Sauleil
¿Puedes desactivar la sugerencia?
Chris S
@AngeDeLaMort: el punto es que te obliga a usar nombres que son incorrectos, por ejemplo var methodXYResultIntArray. Eso va en contra de todos los estándares de codificación y es menos conciso que int[] methodXYResult. Si desea devolver a byte[]del método en el futuro, todos sus nombres de variables son incorrectos. Con tipos explícitos puedes refactorizar esto muy fácilmente. Hay razones para usar var, fe con a Dictionary<string, List<SomeType<int>>>. Pero si el nombre de tipo completo no es demasiado largo y no lo usa newen el lado derecho (o un reparto explícito), no debería sugerirlo.
Tim Schmelter
69

varpuede aumentar la legibilidad del código al tiempo que disminuye la comprensión inmediata del código. De todos modos, puede disminuir la legibilidad del código para otras situaciones. A veces su uso es neutral. La medida de legibilidad para la comprensión no es proporcional, sino que depende de la situación. A veces, ambos aumentan o disminuyen juntos.

El factor es a qué se varestá aplicando y qué tan bien el objetivo admite la ofuscación inmediata de su tipo de datos al lector, o si su información de tipo es necesaria para comprender la parte del programa en cuestión.

Por ejemplo, una mala denominación puede provocar varuna disminución de la comprensión del código. Sin varembargo, esto no es culpa suya:

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

A veces no tiene sentido usar varpara tipos de datos simples cuando el código es más legible en su ausencia:

var num = GetNumber(); // But what type of number?
// vs. 
double num = GetNumber(); // I see, it's a double type. 

A veces varpuede ser útil para ocultar información del tipo de datos que no necesariamente le interesa ver las complejidades de:

    IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG! 
    //vs. 
    var q = from t in d where t.Key == null select t;

    // I simply want the first string, so the last version seems fine.  
    q.First().Key; 

Usted debe utilizar varcuando hay un tipo presente en el anonimato porque no hay un nombre de tipo de llamarlo por:

var o = new { Num=3, Name="" };

Cuando Visual Studio Intellisense proporciona información de tipo a pesar de ello var, debe confiar menos en su comprensión mediante la lectura estricta de códigos sin ayuda. Probablemente sea prudente suponer que no todos pueden tener o usar Intellisense.

En resumen, en base a los ejemplos anteriores, sugeriría que la aplicación de carte blanche varno sea una buena idea porque la mayoría de las cosas se hacen mejor con moderación y en función de las circunstancias en cuestión, como se muestra aquí.

¿Por qué Resharper lo usa todo de manera predeterminada? Sugeriría facilidad, porque no puede analizar los matices de las situaciones para decidir cuándo es mejor no usarlo.

John K
fuente
55
En mi humilde opinión, tus ejemplos son buenas razones para usar var, te obligará a escribir nombres de métodos decentes. GetNumber() -but what type?- bueno, ¿por qué te importa? Si es tan importante saberlo, llame al método GetNumberAsDouble(), entonces es igual de claro y funcionará si tiene un método que regresa stringy otro que regresa double.
nicodemus13
10
@ nicodemus13 Generalmente sabe cuándo le importa el tipo de retorno de una función cuando realmente utiliza el valor de retorno en lugar de cuando está escribiendo la función en sí. Su esquema de nomenclatura sugerido podría conducir a abusos como GetResultsAsIEnumerableOfDouble y todo lo que hace es cambiar la información de tipo que eliminó del lado izquierdo de una asignación mediante el uso de var al lado derecho de la asignación.
Eric
valor var2 = Math.Abs ​​(-3); // Obviamente un tipo de datos numéricos. Lo siento, no estoy de acuerdo con este, completamente, dado que el método Abs tiene 7 sobrecargas que no conducen a nada más que oscuridad al mirarlo, imo
s1cart3r
var también puede conducir a errores lógicos sutiles como: var counter = "0"; cuando lo que quieres es un número entero.
alaniane
42

En ReSharper (8.02, pero probablemente en otras versiones), la opción para la sugerencia "Usar declaración de variable local tipada implícitamente" se puede ajustar a su preferencia , sea lo que sea, abriendo primero el menú de opciones para ReSharper:

Menú de opciones de ReSharper

Luego, en "Código de inspección" ajustando la "Severidad de inspección" del idioma elegido, en mi caso c #:

Desactive la sugerencia de variable local escrita de forma implícita

Como puede ver, hay opciones para ajustar todas las sugerencias que hace ReSharper. Espero que esto ayude a alguien como yo que ya tiene una estrategia de uso 'var' y solo quiere que ReSharper la respete :)

Erikest
fuente
Esto responde a una pregunta diferente que no se hizo en absoluto.
Carles Alcolea
99
Pero es relevante para muchos que lo buscan al llegar aquí. +1
Ori Nachum
24

Me sorprende que nadie haya mencionado que también es más fácil cambiar el tipo de objeto instanciado, porque

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

Es una forma de repetición . Si quiero cambiar AVeryLongTypeNamea una de sus clases derivadas, solo necesito cambiar esto una vez cuando lo use vary aún puedo acceder a los métodos de las clases secundarias.

Aparte de eso, la legibilidad mejorada es un punto importante, pero como otros dijeron, var no debe usarse en exceso, por lo que creo que desactivar la sugerencia en Resharper está absolutamente bien.

Philipp
fuente
Muy útil cuando se llaman métodos de fábrica en lugar de "nuevos"
Ian Ringrose
Si necesita usar 'MyClass' cuando inicialmente escribe el código y funciona, entonces funciona. Cuando necesita cambiarlo, debe ir y cambiarlo a todas partes, especialmente cuando tiene interfaces involucradas. El código no debe ser tratado como un ensayo, debe ser semántico y bien definido.
Piotr Kula
24

'var' se trata de ser claro

El debate principal acerca de si usar la varpalabra clave o no es sobre qué tan legible es el código para usted y otros desarrolladores.

Al igual que si estuviera escribiendo una historia, no hay una respuesta correcta definitiva. Pero veamos algunos ejemplos de esto en inglés simple.

Jake saludó a Bill. No le gustaba, así que se volvió y se fue para otro lado.

¿Quién fue por el otro lado? Jake o Bill? En este caso, usar los nombres "Jake" y "Bill" es como usar el nombre del tipo. Y "Él" y "él" es como usar la varpalabra clave. En este caso, podría ser más específico. Lo siguiente, por ejemplo, es mucho más claro.

Jake saludó a Bill. A Jake no le gustaba Bill, así que se volvió y se fue para otro lado.

En este caso, al ser más específico, la oración fue más clara. Pero ese no siempre será el caso. En algunos casos, ser específico hace que sea más difícil de leer.

A Bill le gustan los libros, así que Bill fue a la biblioteca y sacó un libro que siempre le ha gustado.

En este caso, sería más fácil leer la oración si usáramos "él" y, en algunos casos, omitiéramos su nombre, lo que equivale a usar la varpalabra clave.

A Bill le gustan los libros, así que fue a la biblioteca y sacó un libro que siempre le ha gustado.

Esos ejemplos cubren la esencia, pero no cuentan toda la historia. En esos ejemplos solo había una forma de referirse a la persona. Ya sea usando su nombre o usando un término más general como "él" y "él".

En el caso del código, tenemos 3 formas de ayudar a agregar claridad. El tipo, el nombre de la variable y la asignación. Tome esta línea de código, por ejemplo:

Person p = GetPerson();

La pregunta ahora es si hay suficiente información en esa línea de código para ayudarlo a descubrir qué está pasando.

¿Qué pasa con la siguiente línea de código? ¿Sabrías lo que psignifica en este caso?

var p = GetPerson();

Que tal ahora:

var p = Get();

O ahora:

var person = Get();

O este:

var t = GetPerson();

O esto:

var u = Person.Get();

Si la palabra clave varfunciona en un escenario determinado depende mucho del contexto del código, como cómo se nombran las variables, las clases y los métodos. También depende de la complejidad del código y del resto del código que lo rodea.

Personalmente, me gusta usar la varpalabra clave, es más completa para mí la mayor parte del tiempo. Pero también tiendo a nombrar mis variables después del tipo, así que realmente no estoy perdiendo ninguna información.

Dicho esto, a veces, dependiendo del contexto, hago excepciones, tal es la naturaleza de cualquier cosa compleja, y el software no es más que complejo.

Luis perez
fuente
1
Me gusta más esta respuesta, porque no tengo nada en contra varsiempre y cuando sepa qué es mientras leo esa línea. Si no tengo idea de qué está regresando un método de otra Solución que usa un modelo de dominio diferente, prefiero tener ese tipo definido explícitamente, lo que hace que sea mucho más fácil de leer. +1
Piotr Kula
En todos los casos en que el tipo devuelto no es evidente, estoy de acuerdo en que no debe usar var ya que ahora está omitiendo información útil.
llega el
18

No me gustó esto también.

No quiero que esto se convierta en un debate sobre el uso de var, tiene sus usos, pero no debe usarse en todas partes.

La clave para recordar es que ReSharper está configurado con los estándares de codificación que desee.

Editar: ReSharper y var

LiamB
fuente
13
Después de un año más o menos resistiéndome, casi siempre uso var ahora.
LiamB
15

Veo muchas respuestas correctas, pero me falta la respuesta completa.

Es cierto que ReSharper sobreutiliza varpor defecto. Creo que la mayoría de la gente estaría de acuerdo con eso. También es más fácil de leer cuando varse usa y el tipo es obvio, como cuando se usa una newdeclaración. Vi una publicación que mostraba cómo actualizar la gravedad de la inspección para mostrar solo sugerencias para el uso de var.

Intenté comentar en otras publicaciones primero para agregar dónde establecerlas, pero no tenía la reputación de hacerlo. Aparentemente, tampoco tenía la reputación de publicar mi captura de pantalla de la configuración.

Te explicaré cómo llegar.

En Visual Studio> Menú principal> Resharper> Opciones> Edición de código> C #> Estilo de código> Uso de Var en declaraciones

  • Para tipos incorporados Use tipo explícito
  • Para tipos simples Use 'var' cuando sea evidente
  • En otro lugar use'var '

ingrese la descripción de la imagen aquí

Documentación de ayuda de ReSharper: estilo de sintaxis de código : escritura implícita / explícita (palabra clave 'var'): configure las preferencias de uso de la palabra clave 'var'

Nathan Kovac
fuente
Esto debería ser marcado como la respuesta correcta fuera de los debates de var, este es el enfoque equilibrado
Brian Ogden
¿Podría dar un ejemplo de cómo se decide "dónde evidente"?
llega el
13

Mi regla es esta:

  • ¿Está declarando un tipo primitivo (es decir byte, char, string, int[], double?, decimal, etc.)? -> Usa el tipo:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
  • ¿Está declarando un tipo complejo (es decir List<T>, Dictionary<T, T>, MyObj)? -> Uso var:

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();
Sumner Evans
fuente
Me gustaría estar en desacuerdo, string myStr = "foo";es obvio que es una cuerda. Pondría todos sus ejemplos en el uso de la categoría var ... y las declaraciones que son retornos de un método para usar el tipo de explicidad. Pero al final del día, es lo que usted y su equipo sientan que es mejor para el proyecto en particular.
Dean Meehan
12

Solo me gustaría señalar que se recomienda el uso de "var" en las Convenciones de codificación de C #

cuando el tipo de la variable es obvio desde el lado derecho de la tarea, o cuando el tipo preciso no es importante

así que probablemente por eso la sugerencia está activada por defecto en ReSharper. También proporcionan algunos casos en los que no mejoraría la legibilidad justo debajo del mismo documento.

jose
fuente
Eso es genial cuando sabes que el tipo proviene System.Diagnostics.PerformanceCounter() : puedes distinguir fácilmente el contador de rendimiento de la clase de diagnóstico incorporada. ¿Pero qué tipo se devuelve aquí? var thingyMaBob = GetThatSpecialThing(18,null,(MyEnum)2)? No hay indicios de sincronización, especialmente si tiene más de 100 proyectos en su solución.
Piotr Kula
"Recomendado cuando el tipo de la variable es obvio" y "También proporcionan algunos casos en los que no mejoraría la legibilidad justo debajo en el mismo documento". Honestamente, creo que he perdido tu punto. Mi respuesta dice lo mismo que tú dices.
jose
6

ReSharper recomienda varporque tiende a despejar la creación de objetos.

Compare estos dos ejemplos:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

Es solo una taquigrafía que se supone que es más fácil de leer.

Creo que está bien cuando creas nuevos objetos explícitamente con "nuevo". Sin embargo, en su ejemplo, puede que no sea obvio si las clases no se nombraron correctamente.

Paul Sasik
fuente
6

Por cierto, ReSharper establece una distinción entre "es posible que desee aplicar esta sugerencia a su código" y "su código está roto, ¿quiere que lo solucione?". La varpalabra clave se encuentra en la categoría de sugerencias, junto con cosas como "invertir si para reducir el anidamiento"; No tienes que seguirlo.

Puede configurar qué tan molestas son cada una de sus alertas a través del cuadro de diálogo Opciones, o directamente a través del menú emergente para esa alerta. Puede degradar cosas como la varsugerencia para que sean menos prominentes, o puede actualizar cosas como la alerta 'usar método de extensión' para que aparezca como un error real.

Tim Robinson
fuente
5

La varcaracterística de .Net 3.0 es solo inferencia de tipos , que es segura y a menudo hace que su código sea más fácil de leer. Pero no tiene que hacerlo, y puede desactivar esa recomendación en un compartidor si lo desea.

Klaus Byskov Pedersen
fuente
4

¡Var es asombroso! Me he encontrado con muchos desarrolladores que tienen la impresión de que varestá vinculado a un tipo dinámico, no lo es. Todavía está estáticamente tipado, solo lo decide el compilador.

Aquí hay algunos aspectos positivos sorprendentes de usar var

Menos escribir var es más corto y más fácil de leer, por ejemplo,

Dictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>()Yuk.

var postcodes = new Dictionary<int,IList<string>>()\ o / \ o /

Nombres de variables más descriptivos : tenue pero creo que es importante dejar que la naturaleza fluida del varbrillo brille aquí. Como vares un poco vago, realmente fomenta un nombre de variable más descriptivo en lugar de dejar que el tipo hable por sí mismo.

Menos cambios de código : si cambia el tipo de retorno de una llamada a método. Solo tiene que cambiar la llamada al método, no todos los lugares donde se usa.

Tipos anónimos: los tipos anónimos son un concepto realmente poderoso, especialmente en áreas como los recursos parciales de WebApi . Sin var, no se pueden usar.

Sin embargo, a veces es útil declarar explícitamente tipos y esto me parece más útil en primitivas o estructuras. Por ejemplo, personalmente no encuentro esta sintaxis muy útil:

for(var i = 0; i < 10; i++) 
{

}

vs

for(int i = 0; i < 10; i++) 
{

}

Todo vardepende de las preferencias personales, pero el uso realmente acelerará su desarrollo y desbloqueará todo un mundo de bondades de tipo anónimo.

KnowHoper
fuente
2

No hay diferencia técnica, si utiliza var, el compilador implica el tipo. Si tienes un código como este:

var x = 1;

se supone que x es un int y no se le pueden asignar otros valores.

La palabra clave var es útil si cambia el tipo de la variable; entonces solo tiene que hacer un cambio en lugar de dos:

var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";
eWolf
fuente
1
@AlexKamburov el código de 10 líneas a continuación se romperá de todos modos, no está relacionado con la var.
user3285954
1
@ user3285954 En algunos casos, var puede ocultar el problema y es cuando las cosas se ponen feas. El problema no está en escribir código, el problema está en la mantenibilidad. Algunos argumentan que es más limpio con var, pero a veces lo veo como ofuscación. Está cerca de un debate religioso. brad-smith.info/blog/archives/336 Yo personalmente uso var solo para las declaraciones de Linq y otros lugares donde declarar el tipo es realmente detallado. Creo que var es una buena adición y la gente necesita ver los comentarios de Anders Hejlsberg sobre las razones para presentarlo.
Alex Kamburov
2

La varpalabra clave se introdujo en C # 3.0; nos permite olvidar especificar nuestro tipo explícitamente.

No hay una diferencia real entre si usas

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

o

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

excepto pura legibilidad y menos posibilidades de error.

Parece un ejemplo cliché, pero digamos que lo siguiente puede ayudarlo a comprender:

var myInt = 23;

devuelve un inttipo, mientras que

var myInt = "23";

devuelve un stringtipo

Referencia de MSDN

Daniel May
fuente
2

Especificar un tipo de objeto explícito es de alguna manera redundante. Incluso traducido al inglés, suena redundante: "poner un objeto de tipo X en una variable de tipo X" vs "Poner un objeto de tipo X en una variable".

Sin embargo, el uso de 'var' tiene sus limitaciones . Impide el uso a continuación del polimorfismo, que es pura belleza :

Supongamos que un perro extiende animal; Cat extiende la jerarquía de clases de animales:

Animal x = new Dog();
DoStuffWithDog(x as Dog);

x = new Cat();
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

El mismo código, con x declarado con 'var' no se compilará .

var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);

x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);

void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}

De todos modos, volviendo a la pregunta original, no uso Resharper, pero supongo que es lo suficientemente inteligente como para detectar cuándo no usar 'var'. :-)

xtrem
fuente
44
Casting innecesario (con as) es horrible horrible. Convierte los errores de compilación en errores de tiempo de ejecución si tiene algo como Animal x = new Cat(); DoStuffWithDog(x as Dog); ¿Por qué reutilizar x? Perro x = nuevo perro (), gato y = nuevo gato (), auge no más ambigüedad posible.
Mark Sowul
la conversión (con 'como' o no) podría provocar un error de tiempo de ejecución. ¿Qué es tan 'horrible' sobre el casting cuando sabes lo que estás haciendo? ¿Por qué reutilizar x? El ejemplo aquí es ilustrativo. El objetivo del ejemplo es mostrar cómo usar 'var' puede dar lugar a limitaciones cuando se pretende que una referencia sea polimórfica.
xtrem
55
No, no puede: el polimorfismo es lo contrario de lo que está sucediendo aquí. Esto está tratando de pasar objetos de tipo Animala métodos que toman Dogy Cat. El polimorfismo es la inversa: lo que puede pasar objetos de tipo Dogy Caten un método que toma Animal, por ejemplo void Walk(Animal a): Walk(new Cat()),Walk(new Dog())
Marcos Sowul
No debe reutilizar las variables de esta manera, conduce a errores muy desagradables. No es tan obvio en métodos cortos, pero cuando tenga 15-20 líneas de código, olvidará qué es x. No seas perezoso: var dog = new Dog (); DoStuff (perro); var cat = nuevo Cat (); DoStuff (gato);
user3285954
2
No pelear. No tengo sentimientos por ninguna de las formas de declarar variables (implícitas o explícitas). De hecho, uso al menos uno de cada día. Simplemente estoy destacando que cuando elige el método implícito (var), el compilador decidirá el tipo más estrecho posible para usted. Que no siempre es lo que quieres. Eso es todo.
xtrem
2

En mi opinión, varsolo debería usarse cuando está claro de inmediato cuál es el tipo al definir el valor de la variable.

Ejemplo:

var s = "string value";

Es obvio que ses un string.

Creo que también es apropiado cuando el nombre del tipo de variable es muy complejo.

Ejemplo:

Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();

Aparte de estos escenarios, no veo que se gane nada mediante el uso var, pero puedo pensar en algunos escenarios en los que puede ser perjudicial:

Por ejemplo, un tipo desechable cuyo valor variable del lado derecho no muestra claramente el tipo. Desechar el ID desechable puede olvidarse fácilmente

Ejemplo:

// returns some file writer
var wr = GetWriter();

wr.add("stuff");
wr.add("more stuff");

//...
//...

// Now `wr` needs to be disposed, 
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.
James Wierzba
fuente
1

'var' agrega una especie de elemento "dinámico" a su código (aunque el código permanece, por supuesto, estrictamente escrito). Aconsejo no usarlo en casos donde el tipo no está claro. Considere este ejemplo:

var bar = GetTheObjectFromDatabase();
bar.DoSomething();

ClassA {
  void DoSomething() {
  //does something
  }
}

ClassB {
  void DoSomething() {
  //does something entirely different
  }
}

Si el tipo de retorno de GetTheObjectFromDatabase () se cambia de tipo A a B, no lo notaremos, ya que ambas clases implementan DoSomething (). Sin embargo, el código ahora puede hacer algo completamente diferente.

Esto puede ser tan sutil como que ambos escriban cosas diferentes en un registro, por lo que es posible que no note que es demasiado tarde.

El siguiente uso de var siempre debe estar bien:

var abc = new Something();
lolaldanee
fuente
1

Para aquellos a los que no les gusta el uso constante de "var", también puede evitar que ReSharper se convierta en var por defecto al hacer "introducir variable". Esto fue algo que me frustró durante mucho tiempo, siempre estaba predeterminado a var, y lo cambiaba cada vez.

Esta configuración se encuentra en Edición de código> C #> Estilo de código

ingrese la descripción de la imagen aquí

Derek
fuente
0

No hay diferencia técnica (como señaló eWolf). Puede usar uno u otro, el código CLR generado se verá igual.

En mi opinión, el principal beneficio es que esto tiende a obligarlo a usar una mejor denominación variable. En su ejemplo, 'foo' es una elección bastante pobre para un nombre de variable.

Jaco Pretorius
fuente
0

Según JetBrains (el autor de ReSharper), fomentan el uso de var por defecto.

Desde su sitio web :

El uso de variables locales escritas implícitamente (también conocidas como varpalabras clave) introducidas en C # 3.0 se ha vuelto bastante popular, ya que mejora la legibilidad en muchos escenarios. De forma predeterminada, ReSharper también fomenta el uso de varpalabras clave, pero las preferencias de su uso son configurables de manera flexible; por ejemplo, puede optar por usar tipos explícitos en casos específicos o en cualquier lugar y ReSharper lo ayudará a hacer cumplir sus preferencias.

Jeff Reddy
fuente
¿Dónde puedo configurar cuándo solicitar una declaración de tipo explícita?
user764754