简体   繁体   中英

What are some advantages & disadvantages of type inference in C#?

I have a coworker that is against type inference in C#. I believe most of his arguments surrounded lack of readability. My argument against that is that Visual Studio's intellisense features provide a simple way of viewing types, and reading them from the code isn't as necessary as it might be if we were coding out of notepad.

However, I am curious about the advantages and disadvantages of using type inference in C#. I come from C++ and I know that C++0x's 'auto' has a more objective benefit in that you don't always know the types you're getting (especially when doing heavy template programming). An example is using auto to store the value of Boost.Bind.

In C#, type inference doesn't seem to be as much of a requirement so much as it is a "nice to have" or sugar-coating feature. I think it would be useful for when you are dealing with long types, eg:

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

it would be:

var myVar = obj.GetLazy();

This is much cleaner in my opinion. However, are there any objective arguments for OR against type inference? Is it good programming practice to use it, even in situations where it is arguable that it provides no benefit (eg, using 'var' instead of 'int')?

Some help in understanding how I should use 'var' in my day-to-day coding would be great.

Type inference was invented for exactly the reason you give for C++, you can create anonymous types that don't HAVE a type name (see Lambdas and Linq in particular).

So in that case it's needed.

In the other case (when the type name is known) then it comes down to style. I use var when the type is really obvious:

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

instead of:

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

Because it reduces duplication.

However, I prefer not to use it when the type is not immediately obvious to the reader:

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

But your mileage might vary.

Implicit typing can be useful in some cases, and harmful in others. Eric Lippert recently posted an article on the Uses and misuses of implicit typing that is worth a read.

One thing to remember, var is just for the user, the compiler converts it to its concrete representation when compiling.

The one downside is when using interfaces from a class.

assuming that GetCurrentList() returns a IList<string> :

IEnumerable<string> list = GetCurrentList();

and

var list = GetCurrentList();

are not the same as in the second example, list will be an IList<string> .

I tend to use exlicit typing and usually only use var when it will help the readability of the code and when using anonymous types (because you have to at that point).

I think common sense dictates the following informal rules:

If there's some long name such as :

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

then replacing it with

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

makes sense because you can still tell what the object is.

Something ambiguous, on the other hand, might warrant not using var :

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

Such type inference, in the presence of intellisense, is a roughly good idea, or okay. However, if there were no intellisense, then I would not consider it a good idea. It would be a nightmare instead. Without intellisense, I believe most developers would dislike it, due to the inconvenience caused by lack of intellisense (and exact type, both).

However, even without intellisense, the following would be good:

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

In such situations, type inference is relief, as it avoids lots of typing, and duplicate typing!

With or without intellisense, I prefer to write :

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

I like to use type inference to make code more concise, however I only use it when I can see what type it is on the same line, eg:

var myClass = new MyClass();

BUT

MyClass myClass = RandomFuncThatGetsObject();

I think using var in the first example doesn't affect readability, in fact it makes it more readable, however using var in the second example WOULD affect readability.

Type inference is necessary when you are working with anonymous types:

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

When you use LINQ queries, you usually use anonymous types all the time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM