C# Features That Support LINQ

The following section introduces new language constructs introduced in C# 3.0. Although these new features are all used to a degree with LINQ queries, they are not limited to LINQ and can be used in any context where you find them useful.

Query Expressions

Queries expressions use a declarative syntax similar to SQL or XQuery to query over IEnumerable collections. At compile time query syntax is converted to method calls to a LINQ provider's implementation of the standard query operator extension methods. Applications control the standard query operators that are in scope by specifying the appropriate namespace with a using directive. The following query expression takes an array of strings, groups them according to the first character in the string, and orders the groups.

var query = from str in stringArray  
            group str by str[0] into stringGroup  
            orderby stringGroup.Key  
            select stringGroup;  

For more information, see LINQ Query Expressions.

Implicitly Typed Variables (var)

Instead of explicitly specifying a type when you declare and initialize a variable, you can use the var modifier to instruct the compiler to infer and assign the type, as shown here:

var number = 5;  
var name = "Virginia";  
var query = from str in stringArray  
            where str[0] == 'm'  
            select str;  

Variables declared as var are just as strongly-typed as variables whose type you specify explicitly. The use of var makes it possible to create anonymous types, but it can be used for any local variable. Arrays can also be declared with implicit typing.

For more information, see Implicitly Typed Local Variables.

Object and Collection Initializers

Object and collection initializers make it possible to initialize objects without explicitly calling a constructor for the object. Initializers are typically used in query expressions when they project the source data into a new data type. Assuming a class named Customer with public Name and Phone properties, the object initializer can be used as in the following code:

Customer cust = new Customer { Name = "Mike", Phone = "555-1212" };  

For more information, see Object and Collection Initializers.

Anonymous Types

An anonymous type is constructed by the compiler and the type name is only available to the compiler. Anonymous types provide a convenient way to group a set of properties temporarily in a query result without having to define a separate named type. Anonymous types are initialized with a new expression and an object initializer, as shown here:

select new {name = cust.Name, phone = cust.Phone};  

For more information, see Anonymous Types.

Extension Methods

An extension method is a static method that can be associated with a type, so that it can be called as if it were an instance method on the type. This feature enables you to, in effect, "add" new methods to existing types without actually modifying them. The standard query operators are a set of extension methods that provide LINQ query functionality for any type that implements IEnumerable<T>.

For more information, see Extension Methods.

Lambda Expressions

A lambda expression is an inline function that uses the => operator to separate input parameters from the function body and can be converted at compile time to a delegate or an expression tree. In LINQ programming, you will encounter lambda expressions when you make direct method calls to the standard query operators.

For more information, see:

Auto-Implemented Properties

Auto-implemented properties make property-declaration more concise. When you declare a property as shown in the following example, the compiler will create a private, anonymous backing field that is not accessible except through the property getter and setter.

public string Name {get; set;}  

For more information, see Auto-Implemented Properties.

See Also

Language-Integrated Query (LINQ) (C#)