LINQ and Generic Types

LINQ queries are based on generic types, which were introduced in version 2.0 of the .NET Framework. You do not need an in-depth knowledge of generics before you can start writing queries. However, you may want to understand two basic concepts:

  1. When you create an instance of a generic collection class such as List<T>, you replace the "T" with the type of objects that the list will hold. For example, a list of strings is expressed as List<string>, and a list of Customer objects is expressed as List<Customer>. A generic list is strongly typed and provides many benefits over collections that store their elements as Object. If you try to add a Customer to a List<string>, you will get an error at compile time. It is easy to use generic collections because you do not have to perform run-time type-casting.

  2. IEnumerable<T> is the interface that enables generic collection classes to be enumerated by using the foreach statement. Generic collection classes support IEnumerable<T> just as non-generic collection classes such as ArrayList support IEnumerable.

For more information about generics, see Generics (C# Programming Guide).

IEnumerable&lt;T&gt; variables in LINQ Queries

LINQ query variables are typed as IEnumerable<T> or a derived type such as IQueryable<T>. When you see a query variable that is typed as IEnumerable<Customer>, it just means that the query, when it is executed, will produce a sequence of zero or more Customer objects.

IEnumerable<Customer> customerQuery =
    from cust in customers
    where cust.City == "London" 
    select cust;

foreach (Customer customer in customerQuery)
{
    Console.WriteLine(customer.LastName + ", " + customer.FirstName);
}

For more information, see Type Relationships in LINQ Query Operations (C#).

Letting the Compiler Handle Generic Type Declarations

If you prefer, you can avoid generic syntax by using the var keyword. The var keyword instructs the compiler to infer the type of a query variable by looking at the data source specified in the from clause. The following example produces the same compiled code as the previous example:

var customerQuery2 = 
    from cust in customers
    where cust.City == "London" 
    select cust;

foreach(var customer in customerQuery2)
{
    Console.WriteLine(customer.LastName + ", " + customer.FirstName);
}

The var keyword is useful when the type of the variable is obvious or when it is not that important to explicitly specify nested generic types such as those that are produced by group queries. In general, we recommend that if you use var, realize that it can make your code more difficult for others to read. For more information, see Implicitly Typed Local Variables (C# Programming Guide).

See Also

Reference

Generics (C# Programming Guide)

Other Resources

Getting Started with LINQ in C#