Do you like to use the “var” keyword when writing C#? How often do you use it? When do you use it? Have you ever been bitten by it? Do you consider it a time-saver? Has it made code maintenance easier or harder? These can be tough questions to answer. Your answers might be very specific in nature and different than other developers’ responses.

This article contains my personal opinions about how the C# var keyword should and should not be used. It probably won’t persuade anyone to change how she or he will writes code. Of course, everyone should be following the coding standards followed by their team. I just wanted to voice all my thoughts on this keyword. There are many other articles on the Internet on the use of the C# var keyword but I am trying to identify other thoughts that may have been missed. It was released with C# 3.0 and .NET 3.5.

I also passed the idea of using the C# var keyword to some of the Intertech consultants and I received valuable feedback from them. Thanks, folks!

I personally don’t think I’ll ever understand why so many C# developers prefer (even recommend) almost always declaring local variables as “var” instead of defining the actual data types. Even .NET “best practices” books and programming tools such as JetBrains Resharper recommend using “var” by default. No – I’ll never fully understand the advantages of using this vague data type definition.

When do I like using C# var? I fully agree that “var” can and should be used with LINQ queries that return custom collections. It can be used for defining the variable that holds the result of the query. It can also be used within a “foreach” loop as an iterator for cycling through the results, like this:

static void Main()
{
  List<string> myCars = new List<string>()
    { "Mercury Cougar", "Dodge Dart", "Ford Taurus SHO",
      "Dodge Charger", "Chevrolet Blazer", "Dodge Neon" };

  var dodges = from someCars in myCars
               where someCars.Contains("Dodge")
               orderby someCars descending
               select someCars;

  foreach (var car in dodges)
  { Console.WriteLine(car); }

  Console.WriteLine("\nThe collection type is: \n{0}", dodges.GetType());
  Console.ReadKey();
}

It gives us the following results, with an interesting custom collection that just begs for “var” to be used:

use1

This makes sense! This is one of the primary reasons “var” was created.

This keyword is also used when we create anonymous objects.

var myFastCar = new 
  { Color = "Yellow", Year = "2007", Make = "Dodge", Model = "Charger SRT" };

// Returns:
// { Color = Yellow, Year = 2007, Make = Dodge, Model = Charger SRT }
Console.WriteLine(myFastCar);

As well, I see nothing wrong with using “var” with a local variable declaration in a method, particularly if I’m initializing it with a call to a class’s constructor, like so:

// Oy - this is too much typing!
ReallyFastCarWithRidiculouslyLongClassName myCar1 = 
  new ReallyFastCarWithRidiculouslyLongClassName();

// Better!
var myCar2 = new ReallyFastCarWithRidiculouslyLongClassName();

Heck – this is great! It is ridiculous having to type the class name twice when creating an object, although the second reference is actually a call to the constructor. If you consider using “var” this way, it’s very much the same way VB creates new object instances.

' VB code
Dim myCar1 As New ReallyFastCarWithRidiculouslyLongClassName()

Okay – when do I think it can cause trouble? For one example, when you are calling a factory method that returns an instance of another object. When it comes to code development and more important code maintenance, you cannot simply scan the code with your eyes to truly understand what objects you are working with. You must hover over each method with your mouse to see what type is being returned.

Some of the consultants I Yammered with here at Intertech about “var” mentioned that without it, the fully-defined return types appear as clutter (noise), unnecessarily complicating the code. That makes sense. They also mentioned that if the type returned is only going to be used in one additional instruction, knowing its exact type becomes less important. I see their points.

I also got feedback from a developer who doesn’t like to use “var” but instead will declare an interface variable whenever possible, programming to its implementation. This works great so long as you don’t need to use the standard non-interface members.

In addition, I also received feedback from developers with heavy Python or JavaScript backgrounds that it just felt more natural to use “var” rather than the official type definitions. I can see their points as well.

I also sensed that “var” was more often used with “newer” developers. The “seasoned” gray-haired developers with more years of experience such a working with .NET 1.0, C/C++, or Java may prefer being more specific with their data types.

Here is a code example that I presented the Intertech consultants. It’s from a Microsoft course that I teach.

// Instantiate a type
var type = FourthCoffeeServices.GetHandleErrorType();
...
var constructor = type.GetConstructor(new Type[0]));
...
var initializedObject = constructor.Invoke(new object[0]);

// Invoke methods on the instance
var methodToExecute = type.GetMethod("LogError");
var initializedObject = FourthCoffeeServices.InstantiateHandleErrorType();
...
var response = methodToExecute.Invoke(initializedObject,
               new object[] { "Error message" }) as string;

// Get or set property values on the instance
var property = type.GetProperty("LastErrorMessage");
var initializedObject = FourthCoffeeServices.InstantiateHandleErrorType();
...
var lastErrorMessage = property.GetValue(initializedObject) as string;

As a full time MCT trainer, I think this is code is not helpful at all for teaching reflection to new C# developers. I have actually changed the slides to help students learn. It now looks like this:

// Instantiate a type
Type type = FourthCoffeeServices.GetHandleErrorType();
...
ConstructorInfo constructor = type.GetConstructor(new Type[0]));
...
object initializedObject = constructor.Invoke(new object[0]);

// Invoke methods on the instance
MethodInfo methodToExecute = type.GetMethod("LogError");
object initializedObject = FourthCoffeeServices.InstantiateHandleErrorType();
...
object response = methodToExecute.Invoke(initializedObject,
                  new object[] { "Error message“ }) as string;

// Get or set property values on the instance
PropertyInfo property = type.GetProperty(“LastErrorMessage");
object initializedObject = FourthCoffeeServices.InstantiateHandleErrorType();
...
string lastErrorMessage = property.GetValue(initializedObject) as string;

I think the second example is clearer for students but I can also see how it does appear more cluttered. I strongly believe that if a developer insists on using “var” local variables as return types for methods, they need to be sure to name the variables descriptively and (if possible) name the methods descriptively as well.

Here is another example I presented to them. Yes, I admit that I had to research all the numeric suffixes to write this code. Yeah – I (unfairly) asked them if they could tell me the data types to the variables Numb1 through Numb9.

int iRowCount = 1234; // Explicit declaration
var iColCount = 1234; // Implicit declaration

//var iTotal; // This is illegal.
//var Obj1 = null; // So is this.

var Numb1 = 123D;
var Numb2 = 1.2E+3;
var Numb3 = 123F;
var Numb4 = 123M;
var Numb5 = 4294967295U;
var Numb6 = 8589934590U;
var Numb7 = 9223372036854775807L;
var Numb8 = 18446744073709551615L;
var Numb9 = 18446744073709551615;

Console.WriteLine("123D   is {0}", Numb1.GetType());
Console.WriteLine("1.2E+3 is {0}", Numb2.GetType());
Console.WriteLine("123F   is {0}", Numb3.GetType());
Console.WriteLine("123M   is {0}", Numb4.GetType());
Console.WriteLine("4294967295U is {0}", Numb5.GetType());
Console.WriteLine("8589934590U is {0}", Numb6.GetType());
Console.WriteLine(" 9223372036854775807L is {0}", Numb7.GetType());
Console.WriteLine("18446744073709551615L is {0}", Numb8.GetType());
Console.WriteLine("18446744073709551615 is {0}", Numb9.GetType());

Of course they couldn’t and I don’t blame them for not having all the numeric suffixes and type boundary sizes memorized.

One developer told me that these are terrible variable names (agreed!) and should have names that describe their types. Another developer told me they’d fire the developer that cut this code – LOL!

For the curious, here is what is returned.

use2

Incidently, JetBrains Resharper suggests using “var” with variable declarations by default.

use3

However, is can be simply turned in its configuration setting under Tools | Options… | Resharper Options.

use4

No matter how little or how much you use “var”, I want you to keep something in mind. By using “var”, you are giving full control of how a variable will be defined to someone else. You are depending on the C# compiler to determine the datatype of your local variable – not you. You are depending on the code inside the compiler – someone else’s code outside of your code to determine your data type.

Consider how the compiler works. When it encounters a “var” statement, it understands that it is the responsibility of the compiler to determine the correct data type. If it cannot, it will responsibly raise a compile (build) error. The compiler must follow a specific algorithm that has been written into it to determine the correct data type. The developer is dependent on the code’s algorithm in the compiler to run correctly and determine the correct data type rather than the developer explicitly defining the variable directly. You can certainly study this complex algorithm is the C# compilers’ source code located in the Roslyn project, here: https://github.com/dotnet/roslyn/wiki

Unfortunately, the compiler isn’t always going to determine the correct type or the type you are expecting and this can be a source for errors. After my Yammer conversations with the Intertech consultants, I spoke with one of the Intertech senior developers offline (one on one) about a bug that cost him a couple of hours while slaying it. A variable that was declared as “var” was being assigned a different data type than he was expecting. I suspect there are seasoned C# developers reading this that may have experienced the same thing.

I am sure there are other things I will realize I should have added to this article but these are some of the most important point I wanted to stress here. Thank you for reading and considering. Many thanks also to the Intertech consulting team! Cheers!