按键盘上方向键 ← 或 → 可快速上下翻页,按键盘上的 Enter 键可回到本书目录页,按键盘上方向键 ↑ 可回到本页顶部!
————未阅读完?加入书签已便下次继续阅读!
Software is no different。 Sometimes; even though the code is more plicated and bloated; if the code
is reused often enough; abstracting it saves time; as the end…user code is simplified。 Experience will tell you
when to code specifically or when to write general code that can be reused。 A rule of thumb is to start out by
solving the problem; and if it looks like the code can be reused; then abstract the specific code。
Using Delegates
Since the beginning of Visual Basic; there has been a concept called a delegate。 A delegate is a
type that represents a method signature。 For example; consider the following interface definition。
Interface IExample
Sub Method()
End Interface
The equivalent delegate would look like this:
Delegate Sub Method()
A delegate and interface can share the same role; in that they are two different ways to
represent the signature for a method that you implement elsewhere。 An interface can have
multiple methods and properties。 A delegate is a method signature and can define only the
parameters and return types for that method signature。 The purpose of delegates is to be able
to define a generic method…calling mechanism without needing to add the baggage of imple
menting an interface。
The approach used in the delegate solution to the problem presented in the previous section
is to define a chunk of functionality that performs the iteration; called an iterator。 And then to
do something with the iteration; another chunk of functionality is integrated via a delegate。
Following is the plete rewritten For Each code that uses delegates。 The entire solution
is shown for a big picture purposes; and then will be split into smaller chunks for explanation
purposes。
Imports System。Runtime。pilerServices
Namespace DelegateImplementation
Delegate Sub ProcessValue(ByVal value As Integer)
Module Iterator
' Methods
Public Sub Iterate(ByVal collection As ICollection(Of Integer); _
ByVal cb As ProcessValue)
Dim element As Integer
For Each element In collection
cb(element)
Next
End Sub
End Module
…………………………………………………………Page 262……………………………………………………………
240 CH AP T E R 9 ■ L E A R N IN G AB OU T L I ST S; D E L E G A T E S; A N D L A M B DA E X P R E S SI ON S
Module Tests
' Fields
Private _maxValue As Integer
Private _runningTotal As Integer
Private Sub ProcessMaximumValue(ByVal value As Integer)
If (value 》 Tests。_maxValue) Then
_maxValue = value
End If
End Sub
Private Sub ProcessRunningTotal(ByVal value As Integer)
_runningTotal = _runningTotal + value
End Sub
Public Sub RunAll()
Dim lst As New List(Of Integer)()
lst。Add(1)
lst。Add(2)
lst。Add(3)
lst。Add(4)
_runningTotal = 0
Iterator。Iterate(lst; New ProcessValue(AddressOf ProcessRunningTotal))
Console。WriteLine((〃Running total is (〃 & _runningTotal & 〃)〃))
_maxValue = Integer。MinValue
Iterator。Iterate(lst; New ProcessValue(AddressOf ProcessMaximumValue))
Console。WriteLine((〃Maximum value is (〃 & _maxValue & 〃)〃))
End Sub
End Module
End Namespace
Declaring the Delegate
The beginning of the code is the single line that contains the Delegate keyword。 Any delegate
implementations must match this signature (in our case; ProcessMaximumValue() and
ProcessRunningTotal() match the delegate signature):
Delegate Sub ProcessValue(ByVal value As Integer)
The declaration of the delegate is outside the scope of a class or interface; but the usage of
a delegate must be in the context of a class (as it is in our case)。
The type of the delegate is the name of the method; which is ProcessValue in our case。 The
delegate will be used in the code example to provide a general callback mechanism in the iterator。
The iterator is declared as follows:
…………………………………………………………Page 263……………………………………………………………
C HA P TE R 9 ■ L E AR N I N G A B O U T L I ST S; DE L E G AT E S ; AN D L A M B D A E X PR E SSI O N S 241
Module Extensions
Public Sub Iterate(ByVal collection As ICollection(Of Integer); _
ByVal cb As ProcessValue)
Dim element As Integer
For Each element In collection
cb(element)
Next
End Sub
End Module
A module method can be called as follows:
Iterator。Iterate(lst; delegate)
The first parameter of the Iterate() method is the list to iterate; and the second parameter
is a delegate instance that matches the method signature of the ProcessValue delegate。
In the implementation of Iterate(); each element of the collection is iterated using For
Each; and then in the loop; the variable cb is called as if it were a method。 The calling of cb is
what separates the iterator from the processing of the iteration。 Imagine having implemented
a method that calculates the running total or maximum。 To iterate all of the elements; you
would instantiate the delegate with the method and call Iterate(); as follows:
Iterator。Iterate(lst; New ProcessValue(Proces