Отношения между типами в операциях запросов LINQ (C#)Type Relationships in LINQ Query Operations (C#)

Для эффективного написания запросов следует понимать, как типы переменных связаны друг с другом в полной операции запроса.To write queries effectively, you should understand how types of the variables in a complete query operation all relate to each other. В таком случае вам будет проще работать с примерами LINQ и примерами кода в документации.If you understand these relationships you will more easily comprehend the LINQ samples and code examples in the documentation. Более того, можно будет представить, что происходит в фоновом режиме при неявном типизировании переменных с помощью var.Furthermore, you will understand what occurs behind the scenes when variables are implicitly typed by using var.

Операции запросов LINQ строго типизированы в источнике данных, в самом запросе и при выполнении запроса.LINQ query operations are strongly typed in the data source, in the query itself, and in the query execution. Тип переменных в запросе должен быть совместим с типом элементов в источнике данных и с типом переменной итерации в операторе foreach.The type of the variables in the query must be compatible with the type of the elements in the data source and with the type of the iteration variable in the foreach statement. Строгая типизация гарантирует перехват ошибок во время компиляции, когда их можно будет исправить прежде, чем с ними столкнутся пользователи.This strong typing guarantees that type errors are caught at compile time when they can be corrected before users encounter them.

Для демонстрации связи типов большая часть примеров использует явную типизацию для всех переменных.In order to demonstrate these type relationships, most of the examples that follow use explicit typing for all variables. Последний пример показывает применение тех же принципов даже при использовании неявной типизации с помощью var.The last example shows how the same principles apply even when you use implicit typing by using var.

Запросы, не выполняющие преобразование исходных данныхQueries that do not Transform the Source Data

На следующем рисунке показана операция запроса LINQ to Objects, не выполняющая преобразование данных.The following illustration shows a LINQ to Objects query operation that performs no transformations on the data. Источник содержит последовательность строк, результат запроса также является последовательностью строк.The source contains a sequence of strings and the query output is also a sequence of strings.

Схема, показывающая отношения между типами данных в запросе LINQ.

  1. Аргумент типа источника данных определяет тип переменной диапазона.The type argument of the data source determines the type of the range variable.

  2. Тип выбранного объекта определяет тип переменной запроса.The type of the object that is selected determines the type of the query variable. Здесь name является строкой.Here name is a string. Следовательно, переменная запроса представляет собой IEnumerable<string>.Therefore, the query variable is an IEnumerable<string>.

  3. Итерация переменной запроса выполняется в операторе foreach.The query variable is iterated over in the foreach statement. Поскольку переменная запроса является последовательностью строк, переменная итерации также является строкой.Because the query variable is a sequence of strings, the iteration variable is also a string.

Запросы, выполняющие преобразование исходных данныхQueries that Transform the Source Data

На следующем рисунке показана операция запроса LINQ to SQLLINQ to SQL, выполняющая простое преобразование данных.The following illustration shows a LINQ to SQLLINQ to SQL query operation that performs a simple transformation on the data. В качестве входных данных запрос получает последовательность объектов Customer и выбирает в результате только свойство Name.The query takes a sequence of Customer objects as input, and selects only the Name property in the result. Поскольку Name является строкой, запрос формирует последовательность строк в качестве выходных данных.Because Name is a string, the query produces a sequence of strings as output.

Схема, показывающая запрос, преобразующий тип данных.

  1. Аргумент типа источника данных определяет тип переменной диапазона.The type argument of the data source determines the type of the range variable.

  2. Оператор select возвращает свойство Name вместо целого объекта Customer.The select statement returns the Name property instead of the complete Customer object. Поскольку Name является строкой, аргумент типа custNameQuery является string, а не Customer.Because Name is a string, the type argument of custNameQuery is string, not Customer.

  3. Поскольку custNameQuery представляет собой последовательность строк, переменная итерации цикла foreach также должна быть string.Because custNameQuery is a sequence of strings, the foreach loop's iteration variable must also be a string.

На следующем рисунке показано немного более сложное преобразование.The following illustration shows a slightly more complex transformation. Оператор select возвращает анонимный тип, захватывающий только два члена исходного объекта Customer.The select statement returns an anonymous type that captures just two members of the original Customer object.

Схема, показывающая более сложный запрос, преобразующий тип данных.

  1. Аргумент типа источника данных всегда является типом переменной диапазона в запросе.The type argument of the data source is always the type of the range variable in the query.

  2. Так как оператор select создает анонимный тип, переменная запроса должна неявно типизирована с помощью var.Because the select statement produces an anonymous type, the query variable must be implicitly typed by using var.

  3. Поскольку тип переменной запроса неявный, переменная итерации в цикле foreach также должна быть неявной.Because the type of the query variable is implicit, the iteration variable in the foreach loop must also be implicit.

Разрешение компилятору определять сведения о типеLetting the compiler infer type information

Несмотря на то, что необходимо обладать знаниями об отношениях типов в операции запроса, существует возможность передачи выполнения всех действий компилятору.Although you should understand the type relationships in a query operation, you have the option to let the compiler do all the work for you. Ключевое слово var можно использовать для любой локальной переменной в операции запроса.The keyword var can be used for any local variable in a query operation. Следующий рисунок похож на пример 2, рассмотренный выше.The following illustration is similar to example number 2 that was discussed earlier. Однако компилятор предоставляет строгий тип для каждой переменной в операции запроса.However, the compiler supplies the strong type for each variable in the query operation.

Схема, показывающая поток для типа с неявной типизацией.

Дополнительные сведения о var см. в разделе Неявно типизированные локальные переменные.For more information about var, see Implicitly Typed Local Variables.