Why would var be a bad thing?

Solution 1:

The writers of the .Net Framework Design Guidelines (awesome book) that came out in November 2008 recommend considering using var when the Type is obvious and unambiguous.

On the other hand, if using var would result in an ambiguity when reading the code, as Anton Gogolev pointed out, then it's better not to use it.

in the book (Annex A), they actually give this example:

var names = new List<string>(); // good usage of var

string source = GetSource();
var tokens = source.Split(' '); // ok; most developers know String.Split

var id = GetId(); // Probably not good; it's not clear what the type of id is

It's possible that, to ensure that readability is not subjected to the whims of lowly developers, your organisation has decided that you were not worthy of var and banned it.
It's a shame though, it's like having a nice tool at your disposal but keeping it in a locked glass cabinet.

In most cases, using var for simple types actually helps readability and we must not forget that there is also no performance penalty for using var.

Solution 2:

var q = GetQValue();

is indeed a bad thing. However,

var persistenceManager = ServiceLocator.Resolve<IPersistenceManager>();

is perfectly fine to me.

The bottomline is: use descriptive identifier names and you'll get along just fine.

As a sidenote: I wonder how do they deal with anonymous types when not allowed to use var keyword. Or they don't use them altogether?

Solution 3:

In most cases when uses sensibly (i.e. a simple type initializer where the type and value are the same), then it is fine.

There are some times when it is unclear that you've broken things by changing it - mainly, when the initialized type and the (original) variable type are not the same, because:

  • the variable was originally the base-class
  • the variable was originally an interface
  • the variable was originally another type with an implicit conversion operator

In these cases, you can get into trouble with any type resolution - for example:

  • methods that have different overloads for the two competing types
  • extension methods that are defined differently for the two competing types
  • members that have been re-declared (hidden) on one of the types
  • generic type inference will work differently
  • operator resolution will work differently

In such cases, you change the meaning of the code, and execute something different. This is then a bad thing.

Examples:

Implicit conversion:

static void Main() {
    long x = 17;
    Foo(x);
    var y = 17;
    Foo(y); // boom
}
static void Foo(long value)
{ Console.WriteLine(value); }
static void Foo(int value) {
throw new NotImplementedException(); }

Method hiding:

static void Main() {
    Foo x = new Bar();
    x.Go();
    var y = new Bar();
    y.Go(); // boom
}
class Foo {
    public void Go() { Console.WriteLine("Hi"); }
}
class Bar : Foo {
    public new void Go() { throw new NotImplementedException(); }
}

etc