嗔秤戻幣�哉膵�云利匈嬉蝕湊蛸賜�塋床四衲���萩晦編報炎嘔囚^泡仟 ̄云利匈��
源平慎弌傍利 卦指云慕朕村 紗秘慕禰 厘議慕尺 厘議慕禰 TXT畠云和墮 〆辺茄欺厘議箝誓匂〇

VB2008貫秘壇欺娼宥(PDF鯉塀哂猟井)-及46何蛍

酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何! 泌惚云慕短嗤堋響頼���誅卒亮茂�俊彭堋響��辛聞喘貧圭 "辺茄欺厘議箝誓匂" 孔嬬 才 "紗秘慕禰" 孔嬬��



It allows only objects of type  Example。  

     When you declare a list like this�此�



Dim lst As IList��Of Example�� 



you are saying that the list has a method declared like this�此�



Sub Add��ByVal item As Example�� 



     If you are programming with Visual Basic 2008�察�you should use Visual Basic 2005 and later  

collection classes。 The non´ generics collection classes are�察�to a large degree�察�legacy code。  

Whenever possible�察�use  generics´based collection classes。 

     Now that you know how to manage a collection of objects�察�the next section will present a  

mon collection´related problem and then solve the problem。 



Adding Numbers and Finding Maximum Values 



Let¨s start out with a mon problem�此�addition of all elements in a collection。 Consider the  

following code。 



Dim elements As IList��Of Integer�� = New List��Of Integer���┌� 



elements。Add��1�� 

elements。Add��2�� 

elements。Add��3�� 



Dim runningTotal = 0 

For Each value As Integer In elements 

    runningTotal = runningTotal �� value 

Next 



     This code has three parts�此�initialization of elements�察�adding of numbers to elements�察�and  

iteration of all values in elements that are added to the variable runningTotal。 The code seems  

acceptable。 But let¨s say that you need to write another piece of code where�察�instead of calcu

lating the running total�察�you want to find the maximum value�察�like this�此 �


´´´´´´´´´´´´´´´´´´´´´´Page 258´´´´´´´´´´´´´´´´´´´´´´´

236      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  



          Dim elements As IList��Of Integer�� = New List��Of Integer���┌� 



          elements。Add��1�� 

          elements。Add��2�� 

          elements。Add��3�� 



          Dim maxValue As Integer = Integer。MinValue 

          For Each value As Integer In elements 

              If value 〃 maxValue Then 

                  maxValue = value 

              End If 

          Next 



               The difference between the two code pieces is the bolded code。 The inner loop is different�察 �

          which is a potential problem。 In separate code files�察�the repetition is not apparent�察�but what if  

          you wanted to bine the code bases�拭�The following code adds all elements and finds the  

          maximum value。 



          Dim elements As IList��Of Integer�� = New List��Of Integer���┌� 

          elements。Add��1�� 

          elements。Add��2�� 

          elements。Add��3�� 

          Dim runningTotal As Integer = 0 

          For Each value As Integer In elements 

              runningTotal = runningTotal �� value 

          Next 

          Console。WriteLine�─�RunningTotal �──�& runningTotal & ;��;�� 



          Dim maxValue As Integer = Integer。MinValue 

          For Each value As Integer In elements 

              If value 〃 maxValue Then 

                  maxValue = value 

              End If 

          Next 

          Console。WriteLine�─�Maximum value is �──�&  maxValue & ;��;�� 



               Another variation is as follows�此�



          Dim elements As IList��Of Integer�� = New List��Of Integer���┌� 

          elements。Add��1�� 

          elements。Add��2�� 

          elements。Add��3�� 

          Dim runningTotal As Integer = 0 

          Dim maxValue As Integer = Integer。MinValue 

          For Each value As Integer In elements 

              If value 〃 maxValue Then 

                  maxValue = value 

              End If 

              runningTotal = runningTotal �� value 

          Next 


´´´´´´´´´´´´´´´´´´´´´´Page 259´´´´´´´´´´´´´´´´´´´´´´´

                 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  237 



     For one or two instances�察�writing the For Each loop is not that problematic�察�but it would be  

if you needed to use the iterator code in a dozen places。 This type of code is harder to maintain  

and extend。 One way of being more efficient is to delegate the code to an abstract base class  

that is implemented to calculate the running total or maximum value。 The following is the  

plete code ��you can place the three classes in separate files called IteratorBaseClass。vb�察 �

RunningTotal。vb�察�and MaximumValue。vb if you want to test this��。 



    MustInherit Class IteratorBaseClass  

        Protected Sub New��ByVal collection As IList��Of Integer���� 

            _collection = collection 

        End Sub 



        Public Function Iterate�┌� As IteratorBaseClass 

            Dim element As Integer 

            For Each element In Me。_collection 

                ProcessElement��element�� 

            Next 

            Return Me 

        End Function 



        Protected MustOverride Sub ProcessElement��ByVal value As Integer�� 



        Private _collection As IList��Of Integer�� 

    End Class 



    Class RunningTotal 

        Inherits IteratorBaseClass 

        Public Sub New��ByVal collection As IList��Of Integer���� 

            MyBase。New��collection�� 

            Total = 0 

        End Sub 



        Protected Overrides Sub ProcessElement��ByVal value As Integer�� 

            Total = Total �� value 

        End Sub 



        Public Total As Integer 

    End Class 



    Class MaximumValue 

        Inherits IteratorBaseClass 

        Public Sub New��ByVal collection As IList��Of Integer���� 

            MyBase。New��collection�� 

            MaxValue = Integer。MinValue 

        End Sub 


´´´´´´´´´´´´´´´´´´´´´´Page 260´´´´´´´´´´´´´´´´´´´´´´´

238       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  



                   Protected Overrides Sub ProcessElement��ByVal value As Integer�� 

                       If ��value 〃 MaxValue�� Then 

                           MaxValue = value 

                       End If 

                   End Sub 



                   Public MaxValue As Integer 

               End Class 



           Module Module1 

               Sub Main�┌� 

                   Dim elements As IList��Of Integer�� = New List��Of Integer���┌� 

                   elements。Add��1�� 

                   elements。Add��2�� 

                   elements。Add��3�� 



                   Dim runningTotal As Integer = _ 

                     TryCast��New RunningTotal��elements��。Iterate�┌��察�RunningTotal��。Total 



                   Dim maximumValue As Integer = _ 

                     TryCast��New MaximumValue��elements��。Iterate�┌��察�MaximumValue��。MaxValue 



                   Console。WriteLine�─�RunningTotal �──�& runningTotal & ;��;�� 

                   Console。WriteLine�─�Maximum Value �──�& maximumValue & ;��;�� 

               End Sub 

           End Module 



                The rewritten code is much longer�察�even though the bolded code�察�which represents the  

           user code�察�is much shorter。 However�察�this code still isn¨t right。 The code is ill fitting because the  

           problem that it addresses can be solved using another�察�simpler technique。 So�察�in a nutshell�察�you  

           can say the problem is that you want to solve a single particular technical problem using an  

           elegant piece of code that does not include repeated sections that have been copied and pasted。  

           A better solution is consider the code as two code blocks�察�and in the following section�察�you¨ll  

           see how delegates can solve the problem of adding and keeping a running total。 



                                    WEIGHING THE ADVANTAGES OF REUSING CODE 



             Very often�察�when you write code�察�the code that performs the task directly is shorter and to the point。 When you  

             abstract the code and develop general classes�察�the code will begin to bloat and expand�察�but the advantage is  

             that the code can be reused。 So�察�when is abstracting code worth the effort�拭�

                   Consider the analogy of building a house。 You are constructing the trusses for the house。 You have a  

              blueprint that indicates that you need to build 50 trusses。 You could build each of the 50 trusses individually�察 �

             or you could build a jig to speed up building the trusses。 And herein lies the problem。 If the trusses can be built  

             without a jig in 10 hours�察�and with the jig in 2 hours�察�you would think building the jig was a good idea。 But not  

             so fast。 What if building the jig takes 20 hours�拭�Then the time that you saved by using the jig you lost by  

              building the jig。  


´´´´´´´´´´´´´´´´´´´´´´Page 261´´´´´´´´´´´´´´´´´´´´´´´

                  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  239 



        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��ProcessRunningTotal���� 

。 。 。 

Iterator。
卦指朕村 貧匯匈 和匯匈 指欺競何 壘��16�� 家��13��
酔楯荷恬: 梓囚徒貧圭�鮗� ○ 賜 ★ 辛酔堀貧和鍬匈 梓囚徒貧議 Enter 囚辛指欺云慕朕村匈 梓囚徒貧圭�鮗� ● 辛指欺云匈競何!
梁椣戻幣�� 梁心弌傍議揖扮窟燕得胎��傍竃徭失議心隈才凪万弌誌育断蛍�輌臆惨軼僑〃�燕慕得珊辛參資誼持蛍才将刮襲潜��範寔亟圻幹慕得 瓜寡追葎娼得辛參資誼寄楚署衛、持蛍才将刮襲潜填��