Thư viện tri thức trực tuyến
Kho tài liệu với 50,000+ tài liệu học thuật
© 2023 Siêu thị PDF - Kho tài liệu học thuật hàng đầu Việt Nam

Apress pro LINQ Language Integrated Query in C# 2008 phần 4 ppt
Nội dung xem thử
Mô tả chi tiết
160 CHAPTER 5 ■ NONDEFERRED OPERATORS
This code is functionally equivalent to the previous example. Instead of calling the Where operator
to ensure a single element is in the sequence, I can provide the same sequence filtering operation in
the Single operator itself. This should return the only element in the input sequence whose id is 3.
Here are the results:
Anders Hejlsberg
Remember, if either prototype of the Single operator ends up with no element to return, an
InvalidOperationException is thrown. To avoid this, use the SingleOrDefault operator.
SingleOrDefault
The SingleOrDefault operator is similar to the Single operator except for how it behaves when an
element is not found.
Prototypes
There are two prototypes I cover.
The First SingleOrDefault Prototype
public static T SingleOrDefault<T>(
this IEnumerable<T> source);
This version of the prototype returns the only element found in the input sequence. If the sequence
is empty, default(T) is returned. For reference and nullable types, the default value is null. If more
than one element is found, an InvalidOperationException is thrown.
The second prototype of the SingleOrDefault operator allows you to pass a predicate to determine which element should be returned.
The Second SingleOrDefault Prototype
public static T SingleOrDefault<T>(
this IEnumerable<T> source,
Func<T, bool> predicate);
Exceptions
ArgumentNullException is thrown if any arguments are null.
InvalidOperationException is thrown if the operator finds more than one element for which the
predicate returns true.
Examples
Listing 5-30 is an example of the first SingleOrDefault prototype where no element is found. I have
to get an empty sequence to do this. I’ll use the Where operator and provide a key comparison for a
key that doesn’t exist for this purpose.
Rattz_789-3.book Page 160 Tuesday, October 16, 2007 2:21 PM
CHAPTER 5 ■ NONDEFERRED OPERATORS 161
Listing 5-30. Calling the First SingleOrDefault Prototype Where an Element Is Not Found
Employee emp = Employee.GetEmployeesArray()
.Where(e => e.id == 5).SingleOrDefault();
Console.WriteLine(emp == null ? "NULL" :
string.Format("{0} {1}", emp.firstName, emp.lastName));
I queried for the employee whose id is 5 since I know none exists, so an empty sequence will be
returned. Unlike the Single operator, the SingleOrDefault operator handles empty sequences just
fine. Here are the results:
NULL
Listing 5-31 is the same example where a single element is found. I use the Where operator to
provide a sequence with just one element.
Listing 5-31. Calling the First SingleOrDefault Prototype Where an Element Is Found
Employee emp = Employee.GetEmployeesArray()
.Where(e => e.id == 4).SingleOrDefault();
Console.WriteLine(emp == null ? "NULL" :
string.Format("{0} {1}", emp.firstName, emp.lastName));
This time I specify an id I know exists. Here are the results for the code when an element is
found:
David Lightman
As you can see, the employee has been found. For the second SingleOrDefault prototype, shown
in Listing 5-32, I specify an id that I know exists. Instead of using the Where operator, I embed the filter
into the SingleOrDefault operator call.
Listing 5-32. Calling the Second SingleOrDefault Prototype Where an Element Is Found
Employee emp = Employee.GetEmployeesArray()
.SingleOrDefault(e => e.id == 4);
Console.WriteLine(emp == null ? "NULL" :
string.Format("{0} {1}", emp.firstName, emp.lastName));
This example is functionally equivalent to the previous example except instead of filtering the
elements using the Where operator, I filter them by passing a predicate to the SingleOrDefault operator. Here are the results:
David Lightman
Rattz_789-3.book Page 161 Tuesday, October 16, 2007 2:21 PM
162 CHAPTER 5 ■ NONDEFERRED OPERATORS
Now I will try that with a predicate that will not find a match, as shown in Listing 5-33.
Listing 5-33. Calling the Second LastOrDefault Prototype Where an Element Is Not Found
Employee emp = Employee.GetEmployeesArray()
.SingleOrDefault(e => e.id == 5);
Console.WriteLine(emp == null ? "NULL" :
string.Format("{0} {1}", emp.firstName, emp.lastName));
Since there is no element whose id is 5, no elements are found. Here are the results:
NULL
While no elements were found in the sequence, the SingleOrDefault operator handled the situation
gracefully instead of throwing an exception.
ElementAt
The ElementAt operator returns the element from the source sequence at the specified index.
Prototypes
There is one prototype I cover.
The ElementAt Prototype
public static T ElementAt<T>(
this IEnumerable<T> source,
int index);
If the sequence implements IList<T>, the IList interface is used to retrieve the indexed element
directly. If the sequence does not implement IList<T>, the sequence is enumerated until the indexed
element is reached. An ArgumentOutOfRangeException is thrown if the index is less than zero or greater
than or equal to the number of elements in the sequence.
■Note In C#, indexes are zero-based. This means the first element’s index is zero. The last element’s index is
the sequence’s count minus one.
Exceptions
ArgumentNullException is thrown if the source argument is null.
ArgumentOutOfRangeException is thrown if the index is less than zero or greater than or equal to
the number of elements in the sequence.
Examples
Listing 5-34 is an example calling the only prototype of the ElementAt operator.
Rattz_789-3.book Page 162 Tuesday, October 16, 2007 2:21 PM
CHAPTER 5 ■ NONDEFERRED OPERATORS 163
Listing 5-34. Calling the ElementAt Operator
Employee emp = Employee.GetEmployeesArray()
.ElementAt(3);
Console.WriteLine("{0} {1}", emp.firstName, emp.lastName);
I specified that I want the element whose index is 3, which is the fourth element. Here are the
results of the query:
David Lightman
ElementAtOrDefault
The ElementAtOrDefault operator returns the element from the source sequence at the specified
index.
Prototypes
There is one prototype I cover.
The ElementAtOrDefault Prototype
public static T ElementAtOrDefault<T>(
this IEnumerable<T> source,
int index);
If the sequence implements IList<T>, the IList interface is used to retrieve the indexed element
directly. If the sequence does not implement IList<T>, the sequence will be enumerated until the
indexed element is reached.
If the index is less than zero or greater than or equal to the number of elements in the sequence,
default(T) is returned. For reference and nullable types, the default value is null. This is the behavior
that distinguishes it from the ElementAt operator.
Exceptions
ArgumentNullException is thrown if the source argument is null.
Examples
Listing 5-35 is an example calling the ElementAtOrDefault operator when the index is valid.
Listing 5-35. Calling the ElementAtOrDefault Operator with a Valid Index
Employee emp = Employee.GetEmployeesArray()
.ElementAtOrDefault(3);
Console.WriteLine(emp == null ? "NULL" :
string.Format("{0} {1}", emp.firstName, emp.lastName));
Here are the results of the query:
David Lightman
Rattz_789-3.book Page 163 Tuesday, October 16, 2007 2:21 PM
164 CHAPTER 5 ■ NONDEFERRED OPERATORS
Just as expected, the element at index 3 is retrieved. Now I will try a query with an invalid index
using the code in Listing 5-36.
Listing 5-36. Calling the ElementAtOrDefault Operator with an Invalid Index
Employee emp = Employee.GetEmployeesArray()
.ElementAtOrDefault(5);
Console.WriteLine(emp == null ? "NULL" :
string.Format("{0} {1}", emp.firstName, emp.lastName));
There is no element whose index is 5. Here are the results of the query:
NULL
Quantifiers
The following quantifier operators allow you to perform quantification type operations on input
sequences.
Any
The Any operator returns true if any element of an input sequence matches a condition.
Prototypes
There are two prototypes I cover.
The First Any Prototype
public static bool Any<T>(
this IEnumerable<T> source);
This prototype of the Any operator will return true if the source input sequence contains any
elements. The second prototype of the Any operator enumerates the source input sequence and
returns true if at least one element in the input sequence causes the predicate method delegate to
return true. The source input sequence enumeration halts once the predicate returns true.
The Second Any Prototype
public static bool Any<T>(
this IEnumerable<T> source,
Func<T, bool> predicate);
Exceptions
ArgumentNullException is thrown if any of the arguments are null.
Examples
First I will try the case of an empty sequence, as shown in Listing 5-37. I will use the Empty operator I
covered in the previous chapter.
Rattz_789-3.book Page 164 Tuesday, October 16, 2007 2:21 PM