2011-05-16 24 views
9

Tengo un compañero de trabajo que está en contra de la inferencia de tipo en C#. Creo que la mayoría de sus argumentos se referían a la falta de legibilidad. Mi argumento en contra de eso es que las características intellisense de Visual Studio proporcionan una forma simple de ver los tipos, y leerlos desde el código no es tan necesario como podría ser si estuviéramos sacando la codificación del bloc de notas.¿Cuáles son algunas ventajas y desventajas de la inferencia tipo en C#?

Sin embargo, tengo curiosidad acerca de las ventajas y desventajas del uso de la inferencia de tipos en C#. Vengo de C++ y sé que el 'auto' de C++ 0x tiene un beneficio más objetivo, ya que no siempre se conocen los tipos que se obtienen (especialmente cuando se realiza una programación de plantillas pesadas). Un ejemplo es usar auto para almacenar el valor de Boost.Bind.

En C#, la inferencia de tipos no parece ser tanto un requisito tanto ya que es una característica o "bueno tener"-capa de azúcar. Creo que sería útil para cuando se trata de tipos largos, por ejemplo .:

Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = obj.GetLazy(); 

sería:

var myVar = obj.GetLazy(); 

Esto es mucho más limpio en mi opinión. Sin embargo, ¿hay argumentos objetivos para O contra la inferencia de tipo? ¿Es una buena práctica de programación usarlo, incluso en situaciones donde es discutible que no proporciona ningún beneficio (por ejemplo, usar 'var' en lugar de 'int')?

Un poco de ayuda en la comprensión de cómo debería utilizar 'var' en mi día a día de codificación sería grande.

+1

ReSharper parece decirme que use 'var' mucho ... – NickAldwin

+6

Consulte http://blogs.msdn.com/b/ericlippert/archive/2011/04/20/uses-and-misuses-of- implicit-typing.aspx –

+0

Bueno, si me preguntas, nombrar explícitamente el tipo debe ser una excepción muy rara e incluso entonces debes usar el tipo más general que puedas permitirte usar aquí.Pero, de nuevo, programo principalmente en Python (pato escribiendo) y soy muy aficionado a Haskell (tipo de inferencia) y la tipificación estructural. – delnan

Respuesta

8

La inferencia de tipo fue inventada por exactamente la razón que da para C++, puede crear tipos anónimos que NO TIENEN un nombre tipo (ver Lambdas y Linq en particular).

Entonces en ese caso es necesario.

En el otro caso (cuando se conoce el nombre del tipo), se trata de estilo. Yo uso var cuando el tipo es muy obvio:

// I like this - less duplication and easier to read 
var item = new List<ComplexObjectItem>(); 

en lugar de:

List<ComplexObjectItem> item = new List<ComplexObjectItem>(); 

Debido a que reduce la duplicación.

Sin embargo, prefiero no usarlo cuando el tipo no es inmediatamente obvio para el lector:

// I don't like this - I need to look up what the type is 
var item = ResultOfSomeFunctionWhereICantSeeWhatItIs(); 

Pero su kilometraje puede variar.

2
var myVar = obj.GetLazy(); 

Tal tipo de inferencia, en presencia de IntelliSense, más o menos es una buena idea, o bien. Sin embargo, si no hubiera intellisense, entonces no lo consideraría una buena idea. Sería una pesadilla en su lugar. Sin intellisense, creo que a la mayoría de los desarrolladores no les gustaría, debido a los inconvenientes causados ​​por la falta de intellisense (y el tipo exacto, ambos).

Sin embargo, incluso sin intelisense, lo siguiente sería bueno:

var obj = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>(); 

En tales situaciones, la inferencia de tipos es un alivio, ya que evita un montón de escribir, y duplicar escribir!

Con o sin intelisense, yo prefiero escribir:

Lazy<List<MyNamespace.ISomeVeryLongInterfaceType> obj= obj.GetLazy(); 
+1

Incluso con intellisense no está claro qué tipo se está recuperando aquí, seguramente es mejor si alguien puede echar un vistazo al código y saber lo que está sucediendo, si hay 10 líneas de código en un método como este tendrías que pasar y Pase el cursor sobre cada objeto/levántese intellisense para cada línea donde esto suceda. Me enojaría si tuviera que hacer eso. – jcvandan

4

tipos implícitos puede ser útil en algunos casos, y perjudicial en otros. Eric Lippert publicó recientemente un artículo sobre el Uses and misuses of implicit typing que vale la pena leer.

Una cosa para recordar, var es solo para el usuario, el compilador lo convierte a su representación concreta al compilar.

El único inconveniente es que el uso de interfaces de una clase.

suponiendo que GetCurrentList() devuelve un IList<string>:

IEnumerable<string> list = GetCurrentList(); 

y

var list = GetCurrentList(); 

no son los mismos que en el segundo ejemplo, la lista será un IList<string>.

Tiendo a usar el tipado explícito y usualmente solo uso var cuando ayuda a la legibilidad del código y cuando se usan tipos anónimos (porque hay que hacerlo en ese momento).

4

creo que el sentido común dicta las siguientes reglas informales:

Si hay algún nombre largo, tales como:

Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>>(); 

luego reemplazarlo con

var myVar = new Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>>(); 

tiene sentido porque todavía se puede diga lo que es el objeto

algo ambiguo, por el contrario, podría justificar no usar var:

Lazy<List<MyNamespace.ISomeVeryLongInterfaceType>> myVar = doProcess(); 
2

me gusta utilizar la inferencia de tipos para hacer el código más concisa, sin embargo sólo lo uso cuando puedo ver qué tipo es en la misma línea, por ejemplo:

var myClass = new MyClass(); 

PERO

MyClass myClass = RandomFuncThatGetsObject(); 

I pensar que usar var en el primer ejemplo no afecta la legibilidad, de hecho lo hace más legible, sin embargo, usar var en el segundo ejemplo afectaría la legibilidad.

2

La inferencia de tipos es necesario cuando se trabaja con tipos anónimos:

var x = new { Greeting = "Hello", Name = "World" }; 

Al utilizar consultas LINQ, que suelen utilizar los tipos anónimos todo el tiempo.

Cuestiones relacionadas