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. If you understand these relationships you will more easily comprehend the LINQ samples and code examples in the documentation. Furthermore, you will understand what occurs behind the scenes when variables are implicitly typed by using var
.
LINQ query operations are strongly typed in the data source, in the query itself, and in the query execution. 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. 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
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.
The type argument of the data source determines the type of the range variable.
The type of the object that is selected determines the type of the query variable. Here
name
is a string. Therefore, the query variable is anIEnumerable<string>
.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
The following illustration shows a LINQ to SQL query operation that performs a simple transformation on the data. The query takes a sequence of Customer
objects as input, and selects only the Name
property in the result. Because Name
is a string, the query produces a sequence of strings as output.
The type argument of the data source determines the type of the range variable.
The
select
statement returns theName
property instead of the completeCustomer
object. BecauseName
is a string, the type argument ofcustNameQuery
isstring
, notCustomer
.Because
custNameQuery
is a sequence of strings, theforeach
loop's iteration variable must also be astring
.
The following illustration shows a slightly more complex transformation. The select
statement returns an anonymous type that captures just two members of the original Customer
object.
The type argument of the data source is always the type of the range variable in the query.
Because the
select
statement produces an anonymous type, the query variable must be implicitly typed by usingvar
.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. The keyword var can be used for any local variable in a query operation. 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.
For more information about var
, see Implicitly Typed Local Variables.
Feedback
Submit and view feedback for