Implicitly typed local variables (C# Programming Guide)
Local variables can be declared without giving an explicit type. The var
keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement. The inferred type may be a built-in type, an anonymous type, a user-defined type, or a type defined in the .NET class library. For more information about how to initialize arrays with var
, see Implicitly Typed Arrays.
The following examples show various ways in which local variables can be declared with var
:
// i is compiled as an int
var i = 5;
// s is compiled as a string
var s = "Hello";
// a is compiled as int[]
var a = new[] { 0, 1, 2 };
// expr is compiled as IEnumerable<Customer>
// or perhaps IQueryable<Customer>
var expr =
from c in customers
where c.City == "London"
select c;
// anon is compiled as an anonymous type
var anon = new { Name = "Terry", Age = 34 };
// list is compiled as List<int>
var list = new List<int>();
It is important to understand that the var
keyword does not mean "variant" and does not indicate that the variable is loosely typed, or late-bound. It just means that the compiler determines and assigns the most appropriate type.
The var
keyword may be used in the following contexts:
On local variables (variables declared at method scope) as shown in the previous example.
In a for initialization statement.
for (var x = 1; x < 10; x++)
In a foreach initialization statement.
foreach (var item in list) {...}
In a using statement.
using (var file = new StreamReader("C:\\myfile.txt")) {...}
For more information, see How to use implicitly typed local variables and arrays in a query expression.
var and anonymous types
In many cases the use of var
is optional and is just a syntactic convenience. However, when a variable is initialized with an anonymous type you must declare the variable as var
if you need to access the properties of the object at a later point. This is a common scenario in LINQ query expressions. For more information, see Anonymous Types.
From the perspective of your source code, an anonymous type has no name. Therefore, if a query variable has been initialized with var
, then the only way to access the properties in the returned sequence of objects is to use var
as the type of the iteration variable in the foreach
statement.
class ImplicitlyTypedLocals2
{
static void Main()
{
string[] words = { "aPPLE", "BlUeBeRrY", "cHeRry" };
// If a query produces a sequence of anonymous types,
// then use var in the foreach statement to access the properties.
var upperLowerWords =
from w in words
select new { Upper = w.ToUpper(), Lower = w.ToLower() };
// Execute the query
foreach (var ul in upperLowerWords)
{
Console.WriteLine("Uppercase: {0}, Lowercase: {1}", ul.Upper, ul.Lower);
}
}
}
/* Outputs:
Uppercase: APPLE, Lowercase: apple
Uppercase: BLUEBERRY, Lowercase: blueberry
Uppercase: CHERRY, Lowercase: cherry
*/
Remarks
The following restrictions apply to implicitly-typed variable declarations:
var
can only be used when a local variable is declared and initialized in the same statement; the variable cannot be initialized to null, or to a method group or an anonymous function.var
cannot be used on fields at class scope.Variables declared by using
var
cannot be used in the initialization expression. In other words, this expression is legal:int i = (i = 20);
but this expression produces a compile-time error:var i = (i = 20);
Multiple implicitly-typed variables cannot be initialized in the same statement.
If a type named
var
is in scope, then thevar
keyword will resolve to that type name and will not be treated as part of an implicitly typed local variable declaration.
Implicit typing with the var
keyword can only be applied to variables at local method scope. Implicit typing is not available for class fields as the C# compiler would encounter a logical paradox as it processed the code: the compiler needs to know the type of the field, but it cannot determine the type until the assignment expression is analyzed, and the expression cannot be evaluated without knowing the type. Consider the following code:
private var bookTitles;
bookTitles
is a class field given the type var
. As the field has no expression to evaluate, it is impossible for the compiler to infer what type bookTitles
is supposed to be. In addition, adding an expression to the field (like you would for a local variable) is also insufficient:
private var bookTitles = new List<string>();
When the compiler encounters fields during code compilation, it records each field's type before processing any expressions associated with it. The compiler encounters the same paradox trying to parse bookTitles
: it needs to know the type of the field, but the compiler would normally determine var
's type by analyzing the expression, which isn't possible without knowing the type beforehand.
You may find that var
can also be useful with query expressions in which the exact constructed type of the query variable is difficult to determine. This can occur with grouping and ordering operations.
The var
keyword can also be useful when the specific type of the variable is tedious to type on the keyboard, or is obvious, or does not add to the readability of the code. One example where var
is helpful in this manner is with nested generic types such as those used with group operations. In the following query, the type of the query variable is IEnumerable<IGrouping<string, Student>>
. As long as you and others who must maintain your code understand this, there is no problem with using implicit typing for convenience and brevity.
// Same as previous example except we use the entire last name as a key.
// Query variable is an IEnumerable<IGrouping<string, Student>>
var studentQuery3 =
from student in students
group student by student.Last;
The use of var
helps simplify your code, but its use should be restricted to cases where it is required, or when it makes your code easier to read. For more information about when to use var
properly, see the Implicitly typed local variables section on the C# Coding Guidelines article.