按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
Anonymous types are useful only in the context of the method in which they are declared。
The variable points in the CountCustomers2() method is a collection of anonymous…type
objects that could be iterated as follows:
For Each customer in points
Console。WriteLine(〃Customer (〃 & _
customer。identifier & 〃)(〃 & _
customer。points & 〃)〃)
Next
The piler that translates the LINQ expression knows that the final result set contains
anonymous…type objects with the properties identifier and points。
Processing Multiple Streams
In all of the LINQ examples so far; a single result set has been manipulated; processed; and filtered。
You can process multiple inputs at the same time; but you will get a binatorial type answer。
For example; suppose you had this LINQ:
Dim set1 As Integer() = New Integer() {1; 2; 3; 4; 5}
Dim set2 As Integer() = New Integer() {1; 2; 3; 4; 5}
Dim set3 As Integer() = New Integer() {1; 2; 3; 4; 5}
Dim triples = _
From a In set1 _
From b In set2 _
From c In set3 _
Select New With {a; b; c}
In pseudo…code; the following would be identical。
…………………………………………………………Page 433……………………………………………………………
CH AP T E R 1 5 ■ L E A R N I N G A B OU T L I N Q 411
Dim items As List (Of Object) = New List(Of Object)()
For Each a In set1
For Each b In set2
For Each c In set3
items。Add(New With { a; b; c })
Next
Next
Next
When you specify multiple From clauses; you are creating a looping mechanism where
each item is iterated against the other elements。 This sounds useful; but it can have a disastrous
side effect: a seemingly innocent query can take much longer than it should。 After having
written the individual From statements; you can use Where and Select as usual。
Sorting the Results
After having selected elements; you will probably want to sort the result set。 Using LINQ; you
can sort by anything you deem important。 The obvious approach is to sort according to a number
or letter; but you could also sort according to length of the word。
Regardless of how you sort; in LINQ you use the keywords Order By or the method OrderBy()。
The following is a LINQ example that does an alphabetic sort。
Dim words As String() = { 〃cherry〃; 〃apple〃; 〃blueberry〃 }
Dim sortedWords = _
From w In words _
Order By w _
Select w
The phrase Order By is inserted before Select。 In this case; it will sort the words in ascending
alphabetical order。 The way that the Order By works is that the value of the variable is pared;
rather than the actual variable。If you want to sort in reverse order; you can use the keyword
Descending; as follows:
Dim sortedWords = _
From w In words _
Order By w Descending _
Select w
This approach allows you to perform sorts according to other values。 For example; you
could sort by the length of word; like this:
Dim sortedWords = _
From w In words _
Order By w。Length _
Select w
…………………………………………………………Page 434……………………………………………………………
412 CH AP T E R 1 5 ■ L E A R N I N G A B OU T L I N Q
The Order By queries for the value of w。Length; which returns a number。 If that number
happens to be longer or shorter than another word; it is placed after or before the other word。
You could also sort according to multiple criteria。 For example; you could sort the words
alphabetically and then by length:
Dim sortedWords = _
From w In words _
Order By w; w。Length _
Select w
To sort by multiple criteria; append them to the Order By keywords; each separated by
a ma。
■Note The alphabetical and length sort is fruitless; because when you sort alphabetically; you will auto
matically sort by length。 The example is just for illustrative purposes。
Performing Set Operations
The last major topic that you need to know about when using LINQ is the ability to perform set
operations on a collection。 The major downside; however; to performing set operations is that
you must use the methods; and at the time of this writing; no LINQ mand syntax existed for
set operations。
Knowing about set operations is useful because they enable you to sort and organize multiple
result sets。 The examples in this section involve the Customer type again。 However; to make
sure that the set operations function properly; you need to implement the Equals() and
GetHashCode() methods; like this:
Friend Class Customer
Public Overrides Function Equals(ByVal obj As Object) As Boolean
If TypeOf obj Is Customer Then
Dim otherObj As Customer = TryCast(obj; Customer)
If otherObj。Identifier。pareTo(Identifier) = 0 Then
Return True
End If
End If
Return False
End Function
Public Overrides Function GetHashCode() As Integer
Return Identifier。GetHashCode()
End Function
Public Overrides Function ToString() As String
Return String。Concat(New Object() _
{〃Identifier (〃; Me。Identifier; 〃) Points (〃; Me。Points; 〃)〃})
End Function
…………………………………………………………Page 435……………………………………………………………
CH AP T E R 1 5 ■ L E A R N I N G A B OU T L I N Q 413
Public Identifier As String
Public Points As Integer
End Class
■Note The GetHashCode() implementation here is rudimentary。 In the source code that es with this
book; you will find a GetHashCode library class; which makes it simpler to implement GetHashCode()。 The
source code is in the project ServerSideSpreadsheet/Devspace。Trader。mon/Automators。
Look at how GetHashCode() and Equals() are implemented。 Notice that the points data
member is ignored。 In the case of a customer; this is acceptable; because a customer with iden
tical identifiers but unequal points does not imply two separate customers。
Implementing Equals() and GetHashCode() for custom types is absolutely imperative; because
the set operations use that information to determine whether two objects are identical。 If you
don’t implement either method; the set operations will use the default implementations of
Equals() and GetHashCode(); which are inplete and will give you the wrong results。
The next step is to create two separate lists of customers。 In this example; both lists contain the
same valued customer。 Realize that the identical customer is not the same object instance; but
contains the same values。
Dim customers1 As Customer() = New Customer() { _
New Customer() With {。Identifier = 〃Person 1〃; 。Points = 0}; _
New Customer() With {。Identifier = 〃Person 2〃; 。Points = 10}}
Dim customers2 As Customer() = New Customer() { _
New Customer() With {。Identifier = 〃Person 3〃; 。Points = 0}; _
New Customer() With {。Identifier = 〃Person 2〃; 。Points = 10}}
To get a list