#806 – An Example of Mandatory Use of the var Keyword

When assigning the result of a query expression to a variable, there are cases when you do know the result type and so the use of the var keyword is optional.

However, in some cases, an anonymous type is created to contain the results of the expression.  In these cases, you must use the var keyword, because the correct type is generated internally by the compiler and not available to your code.

In the example below, we get something back that we can iterate on, but each element within the result set is anonymously typed, an object containing Name and Age fields.

            var oldDogs = from aDog in dogs
                                          where aDog.Age > 10
                                          select new { aDog.Name, aDog.Age };

            foreach (var anOldie in oldDogs)
                Console.WriteLine(string.Format("{0}, age {1}", anOldie.Name, anOldie.Age));
Advertisement

#805 – An Example of Discretionary Use of the var Keyword

Below is one example where you may or may not want to use the var keyword.

            var oldDogs = from aDog in dogs
                          where aDog.Age > 10
                          select aDog.Name;

            foreach (var next in oldDogs)
                Console.WriteLine(next);

This works just fine.  We don’t specify the type of the value returned from the query expression, but we know that it’s something that we can iterate on, so we just use var for the result and then var again in the foreach.

The difficulty comes when someone else is going to modify this code.  The query actually returns an enumerable list of strings.  But reading the code, you might make the mistake of thinking that it returns a list of dogs.

We could have been more clear by writing:

            IEnumerable<string> oldDogs = from aDog in dogs
                          where aDog.Age > 10
                          select aDog.Name;

            foreach (string name in oldDogs)
                Console.WriteLine(name);

#804 – Tradeoffs when Using the var Keyword

You’d most often use the var keyword, indicating an implicit type, in the following situations:

  • For anonymous types  (var is required)
  • As the type of the result of a LINQ expression
  • To avoid duplicating a long type name

You should end up using var if its use is required (for anonymous types) or if using var improves the readability of your code.

You must be careful, however, in using var to simplify your code.  In many cases, while its use may make writing your code easier, the omission of a type can make the code less readable, because the person later reading the code may need to first determine the variable’s type before being able to use it.

A good rule of thumb is to use strongly typed variables by default and only use var when it is necessary.

#803 – Situations When You Might Use the var Keyword

The var keyword allows you to avoid entering the full type of a variable, letting the compiler infer the type.  The variable is still strongly-typed, i.e. the type is known at compile time.

There is debate about when you should use var.  It’s use ends up dictated by coding style guidelines or personal preference.

You must use var when dealing with anonymous types because the compiler generates only an internal type name.

var myDog = new { Name = "Kirby", Age = 14 };

You might  use var when using LINQ, when the exact type of the query result is not apparent.

            var someDogs = from aDog in dogs
                          where aDog.Age > 10
                          select aDog.Name + "(" + aDog.Nickname + ")";

You might also use var to avoid having to repeat a type name that is already present in an expression.

            var dogs = new List<Dog>();

#280 – Implicitly-Typed Arrays

In the same way that you can declare an implicitly-typed variable, letting the compiler figure out the type of the variable’s value, you can declare implicitly-typed arrays.

In the example below, we declare and initialize both implicitly-typed variables and implicitly-typed arrays.  The compiler infers the type–shown in the associated comment.

            // Implicitly-typed variables
            var x = 42;         // int
            var s = "Hooey";    // string

            // Implicitly-typed arrays
            var someArray = new[] { 5, 6, 7 };             // int[]
            var arrB = new[] { new Dog("Bob"), null };     // Dog[]

#204 – Three Rules About Using Implicitly-Typed Variables

You can create an implicitly-typed variable using the var keyword.  The type is inferred, rather than declared.

Here are a few additional rules about using implicitly-typed variables.

Rule #1 – You can use var only for local variables

You can’t use var when declaring class fields/properties.

    public class Person
    {
        public var Height;    // Compile-time error
    }

Rule #2 – You must initialize an implicitly-typed variable when you declare it

If you don’t initialize an implicitly-typed variable, the compiler can’t infer the type.

        static void Main()
        {
            var height;   // Error: Implicitly-typed local variables must be initialized
        }

Rule #3 – You must declare implicitly-typed variables one at a time

You can’t declare more than one variable on the same line with var.

        static void Main()
        {
            int i, j, k;   // Declare three int variables

            var x, y, z;   // Error: Implicitly-typed local variables cannot have multiple declarators
        }

#183 – Use var to Tell the Compiler to Figure out the Type

You can use traditional strong-typing in C#, where you explicitly declare the type of every variable.  Or you can use the dynamic keyword for dynamic typing, where data is only type-checked at run-time, rather than compile-time.

You can also use the var keyword when declaring variables.  When you use var, you don’t have to explicitly specify the type–the compiler will figure out the correct type at compile-time.  You’re still using strong-typing in this case, because the type checking is done at compile-time.

The following example still fails to compile.  The compiler figures out that s is of type string, it does type-checking and then complains that the use of Concat is invalid.

            var s = "Sean";
            s = s.Concat(" Sexton");

In the next example, we don’t bother to declare the exact types.

            var s = "Hemingway";
            var backwards = s.Reverse();

            // string
            Console.WriteLine(s.GetType());

            // System.Collections.Generic.IEnumerable<char>
            Console.WriteLine(backwards.GetType());