Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Daniel Solis - Illustrated C# 2010 - 2010.pdf
Скачиваний:
16
Добавлен:
11.06.2015
Размер:
11.23 Mб
Скачать

CHAPTER 21 INTRODUCTION TO LINQ

The Standard Query Operators

The standard query operators comprise a set of methods called an application programming interface (API) that lets you query any .NET array or collection. Important characteristics of the standard query operators are the following:

The collection objects queried are called sequences and must implement the IEnumerable<T> interface, where T is a type.

The standard query operators use method syntax.

Some operators return IEnumerable objects (or other sequences), while others return scalars. Operators that return scalars execute their queries immediately and return a value instead of an enumerable object to be iterated over later.

For example, the following code shows the use of operators Sum and Count, which return ints. Notice the following about the code:

The operators are used as methods directly on the sequence objects, which in this case is array numbers.

The return type is not an IEnumerable object but an int.

class Program

{

static int[] numbers = new int[] {2, 4, 6};

static

void Main( )

 

{

 

 

 

int

total

= numbers.Sum();

int

howMany = numbers.Count();

 

Scalar

Sequence

Operator

object

Console.WriteLine("Total: {0}, Count: {1}", total, howMany);

}

}

This code produces the following output:

Total: 12, Count: 3

564

CHAPTER 21 INTRODUCTION TO LINQ

There are 47 standard query operators that fall into 14 different categories. These categories are shown in Table 21-1.

Table 21-1. Categories of the Standard Query Operators

Name

Number of

Description

 

Operators

 

 

 

 

Restriction

1

Returns a subset of the objects of the sequence, based on selection

 

 

criteria

Projection

2

Selects which parts of the objects of a sequence are finally returned

Partitioning

4

Skips or returns objects from a sequence

Join

2

Returns an IEnumerable object that joins two sequences, based on

 

 

some criterion

Concatenation

1

Produces a single sequence from two separate sequences

Ordering

2

Orders a sequence based on supplied criteria

Grouping

1

Groups a sequence based on supplied criteria

Set

4

Performs set operations on a sequence

Conversion

7

Converts sequences to various forms such as arrays, lists, and

 

 

dictionaries

Equality

1

Compares two sequences for equality

Element

9

Returns a particular element of a sequence

Generation

3

Generates sequences

Quantifiers

3

Returns Boolean values specifying whether a particular predicate is

 

 

true about a sequence

Aggregate

7

Returns a single value representing characteristics of a sequence

 

 

 

565

CHAPTER 21 INTRODUCTION TO LINQ

Query Expressions and the Standard Query Operators

As mentioned at the beginning of the chapter, every query expression can also be written using method syntax with the standard query operators. The set of standard query operators is a set of methods for performing queries. The compiler translates every query expression into standard query operator form.

Clearly, since all query expressions are translated into the standard query operators—the operators can perform everything done by query expressions. But the operators also give additional capabilities that aren’t available in query expression form. For example, operators Sum and Count, which were used in the previous example, can be expressed only using the method syntax.

The two forms, query expressions and method syntax, however, can be combined. For example, the following code shows a query expression that also uses operator Count. Notice that the query expression part of the statement is inside parentheses, which is followed by a dot and the name of the method.

static void Main()

{

var numbers = new int[] { 2, 6, 4, 8, 10 };

int howMany = (from n

in

numbers

where n <

7

select

n).Count();

 

Query expression

Operator

Console.WriteLine("Count: {0}", howMany);

}

This code produces the following output:

Count: 3

566

CHAPTER 21 INTRODUCTION TO LINQ

Signatures of the Standard Query Operators

The standard query operators are methods declared in class System.Linq.Enumerable. These methods, however, aren’t just any methods—they are extension methods that extend generic class

IEnumerable<T>.

Extension methods were covered in Chapters 7 and 19, but the most important thing to remember about them is that they are public, static methods that, although defined in one class, are designed to add functionality to a different class—the one listed as the first formal parameter. This formal parameter must be preceded by the keyword this.

For example, the following are the signatures of three of the operators: Count, First, and Where. At first glance, the signatures of the operators can be somewhat intimidating. Notice the following about the signatures:

Since the operators are generic methods, they have a generic parameter (T) associated with their names.

Since the operators are extension methods that extend IEnumerable<T>, they must satisfy the following syntactic requirements:

They must be declared public and static.

They must have the this extension indicator before the first parameter.

They must have IEnumerable<T> as the first parameter type.

 

Always

 

Name and

First

 

public, static

 

generic param

parameter

 

 

 

 

 

 

public static

int

Count<T>( this IEnumerable<T> source );

public static

T

First<T>( this IEnumerable<T> source );

public static IEnumerable<T>

Where<T>( this IEnumerable<T> source, ... );

 

 

 

 

 

 

 

 

 

Return

Extension

type

indicator

567

CHAPTER 21 INTRODUCTION TO LINQ

For example, the following code shows the use of operators Count and First. Both operators take only a single parameter—the reference to the IEnumerable<T> object.

The Count operator returns a single value, which is the count of all the elements in the sequence.

The First operator returns the first element of the sequence.

The first two times the operators are used in this code, they are called directly, just like normal methods, passing the name of the array as the first parameter. In the following two lines, however, they are called using the extension method syntax, as if they were method members of the array, which is enumerable. Notice that in this case no parameter is supplied. Instead, the array name has been moved from the parameter list to before the method name. There it is used as if it contained a declaration of the method.

The direct syntax calls and the extension syntax calls are completely equivalent in effect—only their syntax is different.

using System.Linq;

...

static void Main( )

{

int[] intArray = new int[] { 3, 4, 5, 6, 7, 9 };

Array as parameter

var count1

= Enumerable.Count(intArray);

// Called directly

var firstNum1

= Enumerable.First(intArray);

// Called directly

var

count2

=

intArray.Count();

//

Called

as

extension

var

firstNum2 =

intArray.First();

//

Called

as

extension

Array as extended object

Console.WriteLine("Count: {0}, FirstNumber: {1}", count1, firstNum1); Console.WriteLine("Count: {0}, FirstNumber: {1}", count2, firstNum2);

}

This code produces the following output:

Count: 6, FirstNumber: 3

Count: 6, FirstNumber: 3

568

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]