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

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

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





               The source code contains four tests。 Each calls the method TranslateHello�┌� with some  

          input and receives the output。 The test happens when the output is verified against an expected  

          result。 The verification tests use the pareTo�┌� function to test for correct translation。  

               Notice the third test�此�



                  If ��Translator。TranslateHello�─�allosss;��。pareTo�──┌�  0�� Then 

                      Console。WriteLine�─�Verify nontranslated word test failed;�� 

                  End If 



               This test expects an explicit failure。 You need to write tests that expect to fail。 Successful  

          tests that are meant to fail ensure that your code does not generate false positives。 A false positive  is  

          when your code is supposed to fail and it does not。 

               The tests are within a method that needs to be called from the Main�┌� method�察�as in the  

          following example�此�



              Sub Main�┌� 

                  TestTranslateHello�┌� 

                  Console。ReadKey�┌� 

              End Sub 



               If you pile and run the tests�察�you will find that one of the tests fails。 The failing test is  

          the fourth one�察�which attempts to translate a word that has whitespace。 Whitespace is space  

          that we humans don¨t notice�察�but is necessary to distinguish words�察�sentences�察�and so on。 Before  


´´´´´´´´´´´´´´´´´´´´´´Page 77´´´´´´´´´´´´´´´´´´´´´´´

                                              CH AP T E R   3   *    L E AR N IN G   AB O U T   ST R I N G   M A N I PU L A TI O N S  55 



we can solve the whitespace problem�察�we need to determine which part of the application is  

not working properly。  



Answering the Question of Responsibility 



The whitespace problem is an interesting one。 The caller explicitly put in the extra spaces�察�but  

is the whitespace a bug�察�or is it data that is passed in incorrectly�拭�

      The problem can be defined in the context of reasonable usage。 Imagine that you¨ve just  

bought a car and you¨re driving it on the highway。 If the car breaks down�察�the warranty will be  

in effect and cover the costs of the car repair。 Now imagine the situation where you think you  

are one of the Dukes from the Dukes of Hazzard。 And being a Duke�察�you drive your new car as  

fast as you can and then perform a flying jump。 The car will jump into air�察�which looks quite  

spectacular�察�but then the car lands。 After that�察�the shocks collapse�察�and the car cannot be driven  

any further。 Even though the car is brand new�察�the Duke did not use the car as envisioned by  

the car manufacturer�察�and thus invalidates the warranty。 

      Getting back to the translation ponent�察�it exposes the method TranslateHello�┌� and  

has responsibilities。 And the caller of TranslateHello�┌� has the responsibility of being reason

able about what can be expected to be translated。 So�察�is whitespace sent by the caller reasonable�拭 �

      If the whitespace is a normal circumstance�察�then the failed test is a bug in the ponent。  

But if the whitespace is not a normal circumstance�察�the caller is wrong and must be fixed。 The  

answer is that the caller is being reasonable�察�and the ponent is not acting properly。 We  

have a bug in the ponent that needs to be fixed。 How do I know that the caller is not being  

reasonable�拭�I made it up�察�because that is how I expected the contract to be implemented。 The  

key is in defining a good contract。 

      The bug in the ponent relates to the problem of how a word is being translated。 We  

used the pareTo�┌� method�察�which means that each character is pared�察�position for  

position。 The test failed because the caller passed in a string with whitespace�察�and the ponent  

expected no whitespace。 This bug is not a surprise�察�because we humans ignore the whitespace�察�but  

puters cannot。  

      Before I explain how to fix the bug�察�I need to take a step back and talk about what a string  

is and how you can figure out what a string can do。  



Investigating the String Type 



String is a class type�察�and thus a reference type。  String is a type that has methods and proper

ties。 Value types like Double and Integer have methods and properties�察�but String is the first  

type you are encountering that is a class in its own right ��Double and Integer are not actually  

classes��。 

      To investigate a type�察�you can read the documentation�察�or you can use IntelliSense。 Reading  

the documentation is not a bad idea�察�but it is the slowest and most cumbersome。 IntelliSense  

is an  IDE approach�察�in which a defined type¨s methods and properties are presented to you in  

an easy´to´prehend manner。 

      The first time you use IntelliSense�察�it can be nerve´racking�察�because it seems like the IDE  

has a life of its own。 There is a convention on how to use IntelliSense�察�as illustrated in Figure 3´2。  

I suggest that you take a few moments to experiment with it。 I also remend that you keep  

IntelliSense active in Visual Basic Express。 


´´´´´´´´´´´´´´´´´´´´´´Page 78´´´´´´´´´´´´´´´´´´´´´´´

56         CH AP T E R   3   *    L E A R N IN G   AB OU T   ST R I N G   M A N I P U L AT IO N S   



           Figure 3´2。  Using IntelliSense on a String typed variable 



                 IntelliSense works on only identified variables that have types。 In Figure 3´2�察�IntelliSense  

           worked because the IDE parsed the code and had the ability to read the metadata associated  

           with the type。 Metadata is data that describes your source code。 Whenever you define a class�察 �

           methods and properties are associated with it。 The method and property descriptions are  

           pieces of metadata that is displayed by IntelliSense。 One of the strengths of  is that all  

           types have metadata。 



           The Basis of All Types�此�Object 



           By default�察�everything in  is an object with a few basic properties and methods。 Four basic  

           methods are associated with every object�此�



                o  Equals�┌��此�Verifies the equality of two objects ��see Figure 3´3��。 



                o  GetHashCode�┌��此�Retrieves a unique number describing the object ��see Figure 3´4��。 Two  

                   objects with the same contents will return the same hash code。 



                o  GetType�┌��此�Retrieves the metadata associated with an object ��see Figure 3´5��。 Allows the  

                   program to play ^Are you a 。 。 。 �拭院�to dynamically determine which methods and proper

                   ties a type has。 It is used by IntelliSense to display a list box。 



                o  ToString�┌��此�Converts the contents of the type into a string ��see Figure 3´6��。 Note that the  

                   default CLR ToString�┌� implementations work only for value types。 


´´´´´´´´´´´´´´´´´´´´´´Page 79´´´´´´´´´´´´´´´´´´´´´´´

                                           CH AP T E R   3   *    L E AR N IN G   AB O U T   ST R I N G   M A N I PU L A TI O N S  57 



                              Calling Equals�┌� asks if variable 

                                      a has a value of 2 

 Dim a As Integer = 2 

 If a。Equals��2�� Then 

     Console。WriteLine�─�2 equals 2�察�as it should be;�� 

 End If 



                        This code will always be 

                        called because 2 equals 2 



Figure 3´3。 Equals�┌� is used to verify the equality of two objects。 



        Don¨t think of a�察�b�察�and c as values associated 

        with a variable。 Think of a�察�b�察�and c as having 

         contents associated with the variables。 The 

       contents of a and b match�察�the contents of c do 

               not match the contents of a and b。 



Dim a As Integer = 2                                The contents of a and b are 

Dim b As Integer = 2                               identical�察�thus�察�GetHashCode�┌� 

Dim c As Integer = 3 

                                                     returns the same number 



If a。GetHashCode�┌� = b。GetHashCode�┌� Then 

    Console。WriteLine�─�2 equals 2�察�as it should be;�� 

End If 



If c。GetHashCode�┌�  b。GetHashCode�┌� Then 

    Console。WriteLine�─�3 does not equal 2�察�as it should be;�� 

End If 



                The contents of c and b are not 

                  equal�察�so GetHashCode�┌� will 

                  return two different numbers 



Figure 3´4。 GetHashCode�┌� retrieves a number describing the object。  



     The four basic methods can be called on every variable that you declare。 You will use  

ToString�┌� when debugging or inspecting the state of an object instance during runtime。  

ToString�┌� returns a human´readable string that contains the state of the object instance。 

     You might use the GetType�┌� method occasionally�察�but your IDE and other tools will use  

it all the time。 Using GetType�┌��察�you have the ability to figure out the capabilities of a variable  

during the execution of a program。 In technical terms�察�GetType�┌� returns the formal metadata  

description of the type。 

     From reading the description of Equals�┌� and GetHashCode�┌��察�you would get the impression  

that these two functions serve the same purpose。 However�察�this is not the case。 


´´´´´´´´´´´´´´´´´´´´´´Page 80´´´´´´´´´´´´´´´´´´´´´´´

58        CH AP T E R   3   *    L E A R N IN G   AB OU T   ST R I N G   M A N I P U L AT IO N S   



               You know that a is a value type 

                 ��as explained in Chapter 1��。 

                However�察�a program does not                       By calling GetType�┌� and 

                 know that it is a value type。                     then IsValueType�察�the 

                                                                  program is dynamically 

           Dim a As Integer = 1                                  asking if a is a value type 



           If a。GetType�┌�。IsValueType = True Then 

               Console。WriteLine�─�a is a value type;�� 

           End If 



               This code will always be called 

              because a is always a value type 



           Figure 3´5。 GetType�┌� retrieves the metadata associated with an object。  



                 Variable a contains the value 

                       3 as a binary value                   Calling ToString�┌� will convert the 

                                                                  binary´based value into a 

                                                                    character´based value 

           Dim a As Integer = 3 



           Dim aAsAString As String = a。ToString�┌� 



           If aAsAString = ;3; Then 

               Console。WriteLine�─�3 has been converted into a string;�� 

           End If 



              The = sign is another way                          ^3 ̄ always equals ^3 ̄ 

                to test if ^3 ̄ equals ^3 ̄                           so this code runs 



           Figure 3´6。  ToString�┌� converts the contents of the type into a string。  



                Let¨s say you¨re moving and you¨ve packed two boxes containing kitchen items。 Both boxes  

           contain five red dishes�察�three silver forks�察�two copper knives�察�and two wineglasses。 If you pare  

          the boxes�察�both  Equals�┌� and GetHashCode�┌� will return equality�察�indicating the boxes contain  

          the same number and color of items。 It is important to understand that even though the two  

          boxes are unique instances containing unique articles�察�their contents are identical。 When you  

           pare object instances using Equals�┌� or GetHashCode�┌��察�you are paring the metadata  

           and value attributes�察�not the unique instances。 

                Now imagine the situation where one of the boxes has wineglasses from IKEA and the other  

          has wineglasses from Pier 1。 If you use the Equals�┌� method to pare the boxes�察�it will return  

           False�察�because the box content details are not identical。 The difference lies in how the glasses  


´´´´´´´´´´´´´´´´´´´´´´Page 81´´´´´´´´´´´´´´´´´´´´´´´

                                                 CH AP T E R   3   *    L E AR N IN G   AB O U T   ST R I N G   M A N I PU L A TI O N S  59 



are described。 In contrast�察�calling GetHashCode�┌� will indicate that the contents of the boxes are  

identical。 This is because GetHashCode�┌� is doing a quick contents identification。 

      The difference between the  Equals�┌� and GetHashCode�┌� methods is perspective。 In the  

example�察�from the perspective of the moving pany�察�the boxes are identical because the  

moving pany does not care whether the wineglasses are from IKEA or Pier 1�察�it will not  

distinguish wineglasses from different panies。 

      The fact that GetHashCode�┌� can return identical numbers for what would seem dissimilar  

object contents can confuse developers。 The way to understand GetHashCode�┌� is that�察�rather  

than being useful to verify equality�察�it helps you verify  inequality。 If two objects return dissim

ilar hash code values�察�then you know the contents are not identical。 The intent of a hash code  

is to generate a quick fingerprint of the contents of an object。 It is not pletely reliable�察�but  

works for the most part。  



                                   WHEN INTELLISENSE IS NOT ENOUGH  



   IntelliSense is very good and will even display ments that explain what the method does ��as illustrated in  

   Figure 3´2��。 Another place to find answers is the Microsoft documentation itself�察�which you can access by  

   selecting Help  Index。 You can use the Look For box to search for a specific type。 For example�察�if you type  

   ^String class ̄ in the Look For box�察�you will see details of the String class�察�which you can then filter using the  

   links at the top of the page。 

         The Microsoft documentation is part of the Microsoft Developer Network ��MSDN�� �─�http��// 

   msdn。microsoft。��。 The MSDN web site contains documentation that helps you figure out the  stan

   dard software development kit �─�SDK�� application programming interface ��API��。 There are literally thou

   sands of types�察�with an explosion of methods and properties。 You will definitely not use all of them in a single  

   application�察�but you will always use the  SDK。 

         In most cases�察�MSDN will be enough to help you figure out when you don¨t know about a specific type。 

    If you want to learn more about concepts�察�you can surf to a web site such as Code Project ��http��// 

   codeproject。��。 Code Project contains plenty of examples for almost every development topic that  

   suits your fancy。 



The Problem�此�Character´by´Character parison 



Let¨s get back to the bug of the whitespace。 The method that caused problems was pareTo�┌�。  

Looking at the MSDN documentation�察�you see the following definition for this method ��found  

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