List
Collection Using LINQAs with arrays, you can use LINQ to Objects to query List
s. In Fig. 9.7, a List
of string
s is converted to uppercase and searched for those that begin with "R"
.
let
ClauseLine 30 uses LINQ’s let
clause to create a new range variable. This is useful if you need to store a temporary result for use later in the LINQ query. Typically, let
declares a new range variable to which you assign the result of an expression that operates on the query’s original range variable. In this case, we use string
method ToUpper
to convert each item
to uppercase, then store the result in the new range variable uppercaseString
. We then use uppercaseString
in the where
, orderby
and select
clauses. The where
clause (line 31) uses string
method StartsWith
to determine whether uppercaseString
starts with the character "R"
. Method StartsWith
performs a case-sensitive comparison to determine whether a string
starts with the string
received as an argument. If uppercaseString
starts with "R"
, method StartsWith
returns true
, and the element is included in the query results. More powerful string
matching can be done using the regular-expression capabilities introduced in the online part of Chapter 16, Strings and Characters: A Deeper Look.
We create the query only once (lines 29–33), yet iterating over the results (lines 37–40 and 58–61) gives two different lists of colors. This demonstrates LINQ’s deferred execution. A LINQ query executes only when you access the results—such as iterating over them or using the Count
method—not when you define the query. This allows you to create a query once and execute it many times. Any changes to the data source are reflected in the results each time the query executes.
Deferred execution can improve performance when a query’s results are not immediately needed.
ToArray
and ToList
There may be times when you want to retrieve a collection of the results immediately. LINQ provides extension methods ToArray
and ToList
for this purpose. These methods execute the query on which they’re called and give you the results as an array or List<T>
, respectively. We use ToArray
in Section 21.12.
Methods ToArray
and ToList
also can improve efficiency if you’ll be iterating over the same results multiple times, as you execute the query only once.
Collection initializers provide a convenient syntax (similar to array initializers) for initializing a collection. For example, lines 12–16 of Fig. 9.7 could be replaced with the following statement:
var items = new List<string> {"aQua", "RusT", "yElLow", "rEd"};
In the preceding declaration, we explicitly created the List<string>
with new
, so the compiler knows that the initializer list contains elements for a List<string>
. The following declaration would generate a compilation error, because the compiler cannot determine whether you wish to create an array or a collection
var items = {"aQua", "RusT", "yElLow", "rEd"};