Неявно типизированные локальные переменные (руководство по программированию на C#)Implicitly typed local variables (C# Programming Guide)

Локальные переменные можно объявлять без указания конкретного типа.Local variables can be declared without giving an explicit type. Ключевое слово var указывает, что компилятор должен вывести тип переменной из выражения справа от оператора инициализации.The var keyword instructs the compiler to infer the type of the variable from the expression on the right side of the initialization statement. Выведенный тип может быть встроенным, анонимным, определяемым пользователем либо типом, определяемым в библиотеке классов .NET.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. Дополнительные сведения об инициализации массивов с var см. в разделе Неявно типизированные массивы.For more information about how to initialize arrays with var, see Implicitly Typed Arrays.

В приведенных ниже примерах показаны различные способы объявления локальных переменных с помощью var: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>();

Важно понимать, что ключевое слово var не означает "variant" и не означает, что переменная является слабо типизированной или имеет позднее связывание.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.

Ключевое слово var можно использовать в следующих контекстах:The var keyword may be used in the following contexts:

  • С локальными переменными (переменными, объявленными в области метода), как показано в предыдущем примере.On local variables (variables declared at method scope) as shown in the previous example.

  • В операторе инициализации for.In a for initialization statement.

    for (var x = 1; x < 10; x++)
    
  • В операторе инициализации foreach.In a foreach initialization statement.

    foreach (var item in list) {...}
    
  • В операторе using.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 и анонимные типыvar and anonymous types

Во многих случаях переменная var не является обязательной и предназначена только для синтаксического удобства.In many cases the use of var is optional and is just a syntactic convenience. Тем не менее если переменная инициализируется с помощью анонимного типа и вам потребуется доступ к свойствам объекта на более позднем этапе, ее необходимо объявить как var.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. Это распространенный сценарий в выражениях запросов LINQ.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. Таким образом, если переменная запроса инициализирована с помощью var, то единственный способ получить доступ к свойствам в возвращаемой последовательности объектов — это использовать var как тип переменной итерации в операторе foreach.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 можно использовать только в том случае, если локальная переменная объявляется и инициализируется в одном и том же операторе; переменная не может инициализироваться в нулевое значение, в группу методов или в анонимную функцию.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 нельзя применять к полям в области видимости класса.var cannot be used on fields at class scope.

  • Переменные, объявленные с помощью var, нельзя использовать в выражении инициализации.Variables declared by using var cannot be used in the initialization expression. Другими словами, это выражение является допустимым выражением: int i = (i = 20);, но вызывает ошибку времени компиляции: var i = (i = 20);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.

  • Если тип с именем var входит в область видимости, то ключевое слово var разрешится в это имя типа и не будет обрабатываться как часть объявления неявно типизированной локальной переменной.If a type named var is in scope, then the var keyword will resolve to that type name and will not be treated as part of an implicitly typed local variable declaration.

Неявное типизирование с ключевым словом var может применяться только к переменным в области локального метода.Implicit typing with the var keyword can only be applied to variables at local method scope. Неявное типизирование недоступно для полей класса C#, так как при обработке кода компилятор столкнется с логическим парадоксом: компилятор должен знать тип поля, но он не может определить тип, пока не проанализирует выражение присваивания, и не может вычислить выражение, не зная тип.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 — это поле класса, которому присваивается тип var.bookTitles is a class field given the type var. Так как поле не имеет выражения для оценки, то компилятор не сможет вывести тип bookTitles.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. Компилятор обнаруживает тот же парадокс при попытке анализа bookTitles: он должен знать тип поля, но обычно он определяет тип var путем анализа выражения, который невозможно определить, если заранее не знать тип.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.

Переменную var можно также использовать в выражениях запросов, где точный сконструированный тип переменной запроса определить непросто.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.

Кроме того, ключевое слово var может пригодиться, если конкретный тип переменной сложно набрать с клавиатуры, а также если он очевиден либо затрудняет чтение кода.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. Использовать var таким образом можно, например, с вложенными универсальными типами — подобные типы применяются в групповых операциях.One example where var is helpful in this manner is with nested generic types such as those used with group operations. В следующем запросе переменная запроса имеет тип IEnumerable<IGrouping<string, Student>>.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;

Ключевое слово var позволяет упростить код, однако его следует использовать только там, где оно действительно необходимо или где оно облегчает понимание кода.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. Дополнительные сведения о том, когда следует использовать ключевое слово var, см. в разделе Неявно типизированные локальные переменные в статье с рекомендациями по написанию кода C#.For more information about when to use var properly, see the Implicitly typed local variables section on the C# Coding Guidelines article.

См. такжеSee also