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

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

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



would instantiate the delegate with the method and call Iterate�┌��察�as follows�此�



Iterator。Iterate��lst�察�New ProcessValue��ProcessRunningTotal���� 

。 。 。 

Iterator。Iterate��lst�察�New ProcessValue��ProcessMaximumValue���� 



     The code that wants to automatically iterate code must provide only a delegate imple

mentation。  



Implementing Methods That Match the Delegate 



Implementing methods that match a delegate is straightforward in that you need to declare  

only a method in a class that has the same method signature。 This can be implemented using  

a shared method or an instance method�察�it does not matter。 The following code demonstrates  

methods that match the ProcessValue delegate¨s signature using both types of methods。 



    Class DelegateImplementations  



        Private Sub InstanceProcess��ByVal value As Integer�� 

        End Sub 



        Private Shared Sub SharedProcess��ByVal value As Integer�� 

        End Sub 

    End Class 



     In the example�察�the InstanceProcess�┌� and SharedProcess�┌� methods match the signature  

of the delegate ProcessValue。 If you have two delegates with identical parameter and return  

type signatures�察�then a method with the same signature can be used for either delegate definition。  

     The following shows how to have the methods be recognized as a delegate。 


´´´´´´´´´´´´´´´´´´´´´´Page 264´´´´´´´´´´´´´´´´´´´´´´´

242       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 instanceMethod As New ProcessValue��AddressOf InstanceProcess�� 

          Dim sharedMethod As New ProcessValue��AddressOf SharedProcess�� 



               These two lines instantiate the delegate using the New keyword�察�and each instantiation has  

          a single constructor parameter�察�which is the method to associate with the delegate instance。  

               Now let¨s look at the running total and maximum value example and see the methods that  

          will be wrapped up by delegates。 



             Module Tests 

                  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 

              End Module 



               The ProcessMaximumValue�┌� and  ProcessRunningTotal�┌� methods both have the same  

          signatures as ProcessValue�察�and therefore are delegate candidates。 In each delegate implemen

          tation�察�the running total is calculated or the maximum value is found。 The following code uses  

          the delegates。 



                  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 



               In the example�察�the RunAll�┌� method instantiates and assigns lst。 Then to iterate the indi

          vidual elements�察�the  Iterator。Iterate�┌� method is called with lst and the  

          ProcessRunningTotal�┌� method。 After having calculated and presented the running total�察�the  

          maximum value is calculated and displayed。  


´´´´´´´´´´´´´´´´´´´´´´Page 265´´´´´´´´´´´´´´´´´´´´´´´

                  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  243 



     The delegate solution is more pact than the previous abstract base class solution。 The  

big advantage is the ability to solve a problem using a smaller�察�piecemeal approach。 It is not  

hard to implement a delegate�察�and it is not hard to use a delegate。 



Understanding Lambda Expressions 



Lambda expressions are an extension of delegates�察�but solve a specific problem。 Let¨s take the  

example of calculating sales tax。 Sales tax in general is a simple calculation in that you take the  

total amount�察�multiply it by the sales tax�察�and add the result to the amount。 This gives you the  

total a customer must pay。 Calculating a sales tax is not difficult�察�but it is something that would  

be nice to encapsulate into a small piece of functionality。 Thus�察�calculating sales tax is an excel

lent use of lambda expressions。 

     A lambda expression is declared as a Function that has a single expression as a body。 Following  

is the declaration of a lambda expression。  



Dim calculate = Function��tax As Double�察�amount As Double�� ��tax * amount�� �� amount 



     The lambda expression is declared as a function without a return type。 The code after the  

brackets is a single expression that uses the parameters to perform some action。 In the example�察 �

that single expression is the calculation of the sales tax that is added to the amount to generate  

a new total。 

     The lambda expression could be used as follows�此�



Console。WriteLine�─�Tax �──�& calculate��0。1�察�100�� & ;��;�� 



     The calculate lambda expression is called with two numbers that are of type Double�察�which  

generates an expression similar to this�此�



Function sdfsdfsdf��tax As Double�察�amount As Double�� As Double 

   Return ��tax * amount�� �� amount 

End Function 



     Notice a return type of Double is declared in the generated code。 The piler did this by  

inferring from the code。 

     Single´expression lambda expressions have some use�察�but their real value is in the ability  

to create a closure that establishes a context。 A closure holds the evaluated lambda expression  

with its bound variables for other functions to use�察�which is how the context is established。 

     Let¨s say that we are going to calculate the sales tax for a particular place like Quebec�察 �

Canada。 The sales tax there is 15�ィ察�and thus when using the lambda expression�察�we abstract  

and create code similar to the following。 



Console。WriteLine�─�Tax �──�& calculate��SalesTax。Quebec�察�100。0�� & ;��;�� 



     The value for the sales tax is held in the property SalesTax。Quebec�察�and whenever we use  

the lambda expression�察�we need to specify the property。  

     With lambda expressions and closure�察�you have the ability to save a context。 For starters�察 �

let¨s redefine the lambda expression to have only a single parameter�此�



Function��amount As Double�� ��tax * amount�� �� amount 


´´´´´´´´´´´´´´´´´´´´´´Page 266´´´´´´´´´´´´´´´´´´´´´´´

244       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  



                Notice that the lambda expression still uses the tax rate in its calculation。 This is where context  

           es in。 We can save the context of a certain tax rate and then use the lambda expression in that  

           context。 To do so�察�we need a lambda expression that returns our new one´parameter lambda  

           expression�此�



           Function��tax As Double�� Function��amount As Double�� ��tax * amount�� �� amount 



                We can set the tax rate with the first lambda expression�察�and then call the second to calcu

          late the tax�此�



           Dim prepareTax = 

            Function��tax As Double�� Function��amount As Double�� ��tax * amount�� �� amount 



           Dim doQuebec = prepareTax��0。1�� 

           Console。WriteLine��doQuebec��100���� 



                The call to prepareTax defines doQuebec as prepareTax��0。1�� and sets the tax variable in the  

           context of doQuebec。 Now when we call doQuebec�察�we can calculate the total amount without  

           ever needing to specify the tax rate again。 

                Lambda expressions allow only a single expression。 If you want to implement a lambda  

           expression that should make a decision�察�you have a problem。 To solve this problem�察�you can  

          use an If statement variation that is like a function。 Imagine a country where the applicable  

           sales tax depends on the amount you purchased。 This logic could be implemented using a  

           closure and ternary If statement�察�as follows�此�



           Dim setMinimumSalesTax = Function��minimumSalesTax As Double�� 

                             Function��amount As Double�� 

                                 If��amount 〃 minimumSalesTax�察�

                                    ��0。15 * amount�� �� amount��_ 

                                    ��0。1 * amount�� �� amount�� 



           Dim calculateTotal = setMinimumSalesTax��100�� 



           Console。WriteLine��calculateTotal��80���� 

           Console。WriteLine��calculateTotal��500���� 



                The ternary  If is a function that has three parameters。 The first parameter is the expres

           sion you want to test。 Typically�察�whatever you would write in a regular If block�察�you would  

          write as the first parameter。 In the example�察�it is a test of whether or not the bought amount  

          is greater than a minimum amount。 The second parameter is an expression that is executed  

          whenever the first parameter results in a True value。 The third parameter executes if the first  

          parameter results in a False value。 

                Another variation of the  If function is a two´parameter version that can be used to test  

          whether or not an object has a value of  Nothing�察�as follows�此�



           Dim cleanUpList = Function��defaultObject As Object��_ 

                                Function��objToTest As Object�� If��objToTest�察�defaultObject�� 


´´´´´´´´´´´´´´´´´´´´´´Page 267´´´´´´´´´´´´´´´´´´´´´´´

                  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  245 



     The implementation of the lambda expression has an  If with two parameters。 The first  

parameter is the object to test for Nothing�察�and the second parameter represents the expression  

to execute if the object is Nothing。  



Learning More About Collection Types 



In the beginning of this chapter�察�I talked about the different collection types�察�but not how to use  

them。 This section presents examples of using the types。 



Using a Plain´Vanilla List 



A plain´vanilla list is a list of specific types such as  Integer�察�Double�察�or some other object type。  

Instantiate the list as follows�此�



Dim lst As List��Of MyType�� = New List��Of MyType���┌� 



     The default type  List is used for most of your coding situations�察�but if you are adding and  

removing elements frequently�察�the following code is better。 



Dim lst As IList��Of MyType�� = New LinkedList��Of MyType���┌� 



     The type  LinkedList implements the logic that was presented in the previous chapter�察 �

whereas  List manipulates a fixed´length array。  LinkedList has a downside in that it does not  

support the IList interface�察�and the sample code will not pile。 Thus�察�to make the code  

work�察�you would need to use  ICollection�此�



Dim lst As ICollection��Of MyType�� = New LinkedList��Of MyType���┌� 



     Add an element to  IList as follows�此�



lst。Add��New MyType�┌��� 



     To add elements to your list according to an order�察�use the following form ��note that  

ICollection doesn¨t have this method��。 



lst。Insert��0�察�New MyType�┌��� 



     This adds an element to the front of the list。 If you are adding elements at the beginning of  

the list or somewhere in the list�察�it is better to use the  LinkedList type�察�as it is more efficient。  

Using the class  List incurs an array copy resource penalty。 

     You can also add one list to another�此�



Dim lst As List��Of MyType�� = New List��Of MyType���┌� 

Dim lstToBeAdded As List��Of MyType�� 

lst。AddRange��lstToBeAdded�� 

lst。InsertRange��0�察�lstToBeAdded�� 



     The AddRange�┌� method is used to append the list lstToBeAdded to lst。 The InsertRange�┌�  

method inserts all of the elements in lstToBeAdded to the front of the list lst。 


´´´´´´´´´´´´´´´´´´´´´´Page 268´´´´´´´´´´´´´´´´´´´´´´´

246       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  



                Delete an element from the list like this�此�



           lst。Remove��existingMyType�� 



                The Remove�┌� method expects an instance of a type to remove from the list。  

                To delete a particular element at a particular index�察�use the following form。 



           lst。RemoveAt��0�� 



                This code would remove the element at the front of the list。 



          Using a Key/Value Pair List 



          A key/value pair list is a list that has a cross´reference。 It is like a dictionary where you have  

          a word and associated meaning。 In puting terms�察�the word is a type and its definition is  

          another type。 The word is a key and the definition is a value。 A key/value pair definition would  

          be as follows�察�using the  IDictionary interface and Dictionary class。 



          Dim dictionary As IDictionary��Of String�察�Object�� = _ 

            New Dictionary��Of String�察�Object���┌� 



               You could also use SortedDictionary�察�but that implies the elements within the list are sorted。 

                To add values to the dictionary�察�use the Add�┌� method�此�



                  dictionary。Add�─�List;�察�lst�� 

                  dictionary。Add�─�List To Be Added;�察�lstToBeAdded�� 



               When working with  IDictionary objects�察�you might want to know whether or not a key is  

          available。 The following code is used to verify if a key exists。 



           If dictionary。ContainsKey�─�List;�� Then 

              。 。 。 

           End If 



                If you want to iterate the keys�察�use this form�此�



           For Each key As String In dictionary。Keys 

          Next 



                Iterate the values as follows�此�



           For Each value As Object In dictionary。Values 

          Next 



          Using a Stack 



          A  Stack is a special list that behaves like a stack of paper on a table。 When you add three items  

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