Partilhar via


Local variable type inference in C# 3.0

In C# 1.0 type declaration was very simple:

- Specify the type name (if an array then append [] to the end of the type)

- Follow by a local variable name

Here are some examples of this:

int i = 23;

double[] ds = new double[] { 1.0, 2.0 };

In C# 2.0 with the introduction of generics, it got slightly more complex. We can now compose new types and they look rather elaborative, and certainly not concise:

Dictionary<int, Queue<string>> dic =
new Dictionary<int, Queue<string>>();

Look closer at the above dictionary creation. You’ll soon notice that the type is repeated at both sides of the assignment and poses the logical question: Couldn’t we infer the type of the local variable (dic) automatically from the right hand side? Well, the answer to that is yes! Indeed, the type of the local variable could have been inferred at compile time by the compiler.

In C# 3.0 there is a new feature called “Implicitly typed local variables” which allows the type of a local variable being declared to be inferred from the expression which is used to initialise the variable. The var keyword is used as the type name for the variable.

There are a couple of initial points to mention in here:

- No variable called var should be in scope

- For backward compatibility reason, if there is a type called var then a variable of this type is declared

Let’s see some examples for this:

int i = 23;

double[] ds = new double[] { 1.0, 2.0 };

Dictionary<int, Queue<string>> dic =
new Dictionary<int, Queue<string>>();

The code above is precisely equivalent to the following implicitly typed declarations:

var i = 23;

var ds = new double[] { 1.0, 2.0 };

var dic = new Dictionary<int, Queue<string>>();

The second listing is more concise meaning that there is less code to achieve the same functionality as the first listing.

When dealing with type inference, the var keyword might be mistaken for the var keyword in languages such as JavaScript in which var means a variant type. The way var should be read in C# is “The type of the right hand side”. It is certainly not equivalent to a variant in JavaScript or VB6. In fact, we don’t have variant types in .NET and everything is strongly typed. It is also worth mentioning that using the var keyword is not the same as using the object type in .NET.

The C# 3.0 specification points out the following restrictions on the declarator in an implicitly typed local variable declaration:

- The declarator must include an initialiser (var i = 23;)

- The initialiser must be an expression and cannot be the null type at compile time
(Error: var x = null;)

- The local variable declaration cannot include multiple declarators

- The initialiser cannot refer to the declared variable itself
(Error: var x = x++;)

Where else except for local variable declaration can I use the var keyword?

- For declaring the variable used in the initialiser of a for loop

- Inside a using statement

- For the iteration variable of a foreach

Type inference is certainly a nicety to have however when used with anonymous types, it becomes a necessity (‘Anonymous types’ is yet another new feature of C# 3.0):

Customer c = GetCustomer();

var d = new { Name = c.Name, City = c.City };
Creation and initialisation of an anonymous type

An anonymous type is created automatically by the compiler at compile time. At design time we do not know the name of the type (hence the word “Anonymous”). So without the var keyword, it is probably impossible to declare a local variable that can hold an instance of the anonymous type.

Here is an example of type inference in a foreach:

string[] strs = new string[] { "hi", "bye" };
//s is inferred by the compiler to be string
foreach (var s in strs)
{
s.XXX(); // IntelliSense here will treat s as string
}

Comments

  • Anonymous
    May 31, 2007
    I like it. It's similar to the way VB.NET can handle variables, but it remains strongly typed. Cool!