Report

Visual Basic 2005

To view this page ensure that Adobe Flash Player version 9.0.124 or greater is installed.

Get Adobe Flash player
Please login or register to make a comment!

...Description...... more. less.

in another class.<br><br> My.WebServices Thisobjectprovidesadefaultproxy-classinstanceforeveryweb service.Forexample,ifyourprojectusestwowebreferences,you canaccessaready-madeproxyclassforeachonethroughthis object. Finally,therearetwoother My objectsthatprovideeasyaccesstothe configuration settings and resources: T ired of hun t ing through the extensive .NET class library in search of what you need? With the new My objects, you can quickly find some ofthemostuseful f eatures .NET has to offer.<br><br> ,ch02.11378 Page 28 Thursday, April 21, 2005 1:32 PM Use the My Objects to Program Common Tasks29 My.Settings Thisobjectallowsyoutoretrievecustomsettingsfromyourapplica- tion 9s XML configuration file. My.Resources Thisobjectallowsyoutoretrieve resources 4blocksofbinaryortext datathatarecompiledintoyourapplicationassembly.Resourcesare typically used to store localized strings, images, and audio files. WARNING Notethatthe My objectsareinfluencedbytheprojecttype.For example,whencreatingaweborconsoleapplication,youwon 9tbe able to use My.Forms.<br><br> Someofthe My classesaredefinedinthe Microsoft.VisualBasic. MyServices namespace,whileothers,suchastheclassesusedforthe My.Settings and My.Resources objects,arecreateddynamicallyby VisualStudio2005whenyoumodifyapplicationsettingsandadd resources to the current project. Totryoutthe My object,youcanuseVisualStudioIntelliSense.Justtype My ,followedbyaperiod,andtakealookattheavailableobjects,as showninFigure2-1.Youcanchooseoneandpresstheperiodagainto step down another level.<br><br> Figure2-1. Browsing the My objects ,ch02.11378 Page 29 Thursday, April 21, 2005 1:32 PM 30Chapter2:The Visual Basic Language Totryasimpleexamplethatdisplayssomebasicinformationusingthe My object,createanewconsoleproject.Then,addthiscodetothe Main() routine: Console.WriteLine(My.Computer.Name) Console.WriteLine(My.Computer.Clock.LocalTime) Console.WriteLine(My.Application.CurrentDirectory) Console.WriteLine(My.User.Identity.Name) Whenyourunthiscode,you 9llseesomeoutputintheconsolewindow, whichshowsthecomputername,currenttime,applicationdirectory,and user: SALESSERVER 2005-10-1 8:08:52 PM C:\Code\VBNotebook\1.07\MyTest\bin MATTHEW WARNING The My objectalsohasa cdarkside. dUseofthe My objectmakesit moredifficulttoshareyoursolutionwithnon-VBdevelopers, because other languages, such as C#, don 9t have the same feature. Where can I learn more?<br><br> Youcanlearnmoreaboutthe My objectandseeexamplesbylookingup the cMyObject dindexentryintheMSDNHelp.Youcanalsolearnmore byexaminingsomeofthisbook 9sotherlabsthatusethe My object.Some examples include: "Using My.Application toretrievedetailsofyourprogram,suchasthe currentversionandthecommand-lineparametersusedtostartit (see the cGet Application Information d lab in this chapter). "Using My.Resources toloadimagesandotherresourcesfromthe applicationassembly(seethe cUseStronglyTypedResources dlabin this chapter). "Using My.Settings toretrieveapplicationandusersettings(seethe cUse Strongly Typed Configuration Settings d lab in this chapter).<br><br> "Using My.Forms tointeractbetweenapplicationwindows(seethe cCommunicate Between Forms d lab in Chapter3). "Using My.Computer toperformfilemanipulationandnetworktasksin Chapters 5 and 6. "Using My.User toauthenticatethecurrentuser(seethe cTestGroup Membership of the Current User d lab in Chapter6).<br><br> ,ch02.11378 Page 30 Thursday, April 21, 2005 1:32 PM Get Application Information31 Get Application Information The My.Application objectprovidesawealthofinformationrightat yourfingertips.Gettingthisinformationisaseasyasretrievinga property. How do I do that? Theinformationinthe My.Application objectcomesinhandyinavari- ety of situations.<br><br> Here are two examples: "Youwanttogettheexactversionnumber.Thiscouldbeusefulifyou wanttobuildadynamicAboutbox,orcheckwithawebserviceto make sure you have the latest version of an assembly. "Youwanttorecordsomediagnosticdetails.Thisbecomesimportant ifaproblemisoccurringataclientsiteandyouneedtologsome general information about the application that 9s running. Tocreateastraightforwardexample,youcanusethecodein Example2-1inaconsoleapplication.Itretrievesallofthesedetailsand displays a complete report in a console window.<br><br> Example2-1 . Retrieving information from My.Application ' Find out what parameters were used to start the application. Console.Write("Command line parameters: ") For Each Arg As String In My.Application.CommandLineArgs Console.Write(Arg & " ") Next Console.WriteLine() Console.WriteLine() ' Find out some information about the assembly where this code is located.<br><br> ' This information comes from metadata (attributes in your code). Console.WriteLine("Company: " & My.Application.Info.CompanyName) Console.WriteLine("Description: " & My.Application.Info.Description) Console.WriteLine("Located in: " & My.Application.Info.DirectoryPath) Console.WriteLine("Copyright: " & My.Application.Info.Copyright) Console.WriteLine("Trademark: " & My.Application.Info.Trademark) Console.WriteLine("Name: " & My.Application.Info.AssemblyName) Console.WriteLine("Product: " & My.Application.Info.ProductName) Console.WriteLine("Title: " & My.Application.Info.Title) Console.WriteLine("Version: " & My.Application.Info.Version.ToString()) Console.WriteLine() Using t he My.Application object, you can get information about the current version of your application,where it 9s located, and what parameters were used to start it. ,ch02.11378 Page 31 Thursday, April 21, 2005 1:32 PM 32Chapter2:The Visual Basic Language TIP VisualStudio2005includesaQuickConsolewindowthatactsasa lightweightversionofthenormalcommand-linewindow.Insome cases,thiswindowisalittlebuggy.Ifyouhavetroublerunninga sampleconsoleapplicationandseeingitsoutput,justdisablethis feature.Todoso,selectTools  Options,makesurethe cShowall settings dcheckboxischecked,andselecttheDebugging  General tab.Thenturnoff cRedirectallconsoleoutputtotheQuickCon- sole window. d Beforeyoutestthiscode,itmakessensetosetupyourenvironmentto ensurethatyouwillseemeaningfuldata.Forexample,youmightwant totellVisualStudiotosupplysomecommand-lineparameterswhenit launchestheapplication.Todothis,double-clicktheMyProjecticonin theSolutionExplorer.Then,choosetheDebugtabandlookforthe cCom- mandlineparameters dtextbox.Forexample,youcouldaddthree parameters by specifying the command line /a /b /c .<br><br> Ifyouwanttosetinformationsuchastheassemblyauthor,product,ver- sion,andsoon,youneedtoaddspecialattributestothe AssemblyInfo.vb file,whichisn 9tshownintheSolutionExplorer.Toaccessit,youneedto selectSolution  ShowAllFiles.You 9llfindthe AssemblyInfo.vb fileunder the My Projects node. Here 9s a typical set of tags that you might enter: <Assembly: AssemblyVersion("1.0.0.0")> <Assembly: AssemblyCompany("Prosetech")> <Assembly: AssemblyDescription("Utility that tests My.Application")> <Assembly: AssemblyCopyright("(C) Matthew MacDonald")> <Assembly: AssemblyTrademark("(R) Prosetech")> <Assembly: AssemblyTitle("Test App")> <Assembly: AssemblyProduct("Test App")> Allofthisinformationisembeddedinyourcompiledassemblyas metadata. Nowyoucanrunthetestapplication.Here 9sanexampleoftheoutput you 9ll see: Command line parameters: /a /b /c Company: Prosetech Description: Utility that tests My.Application Located in: C:\Code\VBNotebook\1.08\ApplicationInfo\bin Copyright: (C) Matthew MacDonald Trademark: (R) Prosetech Name: ApplicationInfo.exe Product: Test App Title: Test App Version: 1.0.0.0 N ewinVB2005is theabilitytoadd application information in a special dialog box.<br><br> T o use this f eature, double- click the My P roject item in the Solution E xplorer, select theAssemblytab, and click the Assembly I nformation button. ,ch02.11378 Page 32 Thursday, April 21, 2005 1:32 PM Use Strongly Typed Resources33 What about... &gettingmoredetaileddiagnosticinformation?The My.Computer.Info objectalsoprovidesadashofdiagnosticdetailswithtwousefulproper- ties.<br><br> LoadedAssemblies providesacollectionwithalltheassembliesthat arecurrentlyloaded(andavailabletoyourapplication).Youcanalso examinetheirversionandpublisherinformation. StackTrace providesa snapshotofthecurrentstack,whichreflectswhereyouareinyourcode. Forexample,ifyour Main() methodcallsamethodnamed A() thatthen callsmethod B() ,you 9llseethreeofyourmethodsonthestack 4 B() , A() , and Main() 4in reverse order.<br><br> Here 9s the code you can add to start looking at this information: Console.WriteLine("Currently loaded assemblies") For Each Assm As System.Reflection.Assembly In _ My.Application.Info.LoadedAssemblies Console.WriteLine(Assm.GetName().Name) Next Console.WriteLine() Console.WriteLine("Current stack trace: " & My.Application.Info.StackTrace) Console.WriteLine() Use Strongly Typed Resources Inadditiontocode,.NETassembliescanalsocontain resources 4 embeddedbinarydatasuchasimagesandhardcodedstrings.Even though.NEThassupportedasystemofresourcessinceVersion1.0, VisualStudiohasn 9tincludedintegrateddesign-timesupport.Asa result,developerswhoneedtostoreimagedatausuallyaddittoacon- trolthatsupportsitatdesigntime,suchasa PictureBox or ImageList . Thesecontrolsinsertthepicturedataintotheapplicationresourcefile automatically. InVisualStudio2005,it 9sdramaticallyeasiertoaddinformationtothe resourcesfileandupdateitafterward.Evenbetter,youcanaccessthis information in a strongly typed fashion from anywhere in your code.<br><br> How do I do that? Inordertotryusingastronglytypedresourceofanimageinthislab, you need to create a new Windows application before continuing. Toaddaresource,startbydouble-clickingtheMyProjectnodeinthe SolutionExplorer.Thisopensuptheapplicationdesigner,whereyoucan configureahostofapplication-relatedsettings.Next,clicktheResources S t rongly t yped resources let you embed static data such as images into your compiled assemblies, and access it easily in your code.<br><br> ,ch02.11378 Page 33 Thursday, April 21, 2005 1:32 PM 34Chapter2:The Visual Basic Language tab.IntheCategoriesdrop-downlistbox,selectthetypeofresourcesyou wanttosee(strings,images,audio,andsoon).Thestringviewshowsa gridofsettings.Theimageviewisalittledifferent 4bydefault,itshowsa thumbnail of each picture. Toaddanewpicture,selecttheImagescategoryfromthedrop-downlist andthenselectAdd  ExistingFilefromthetoolbar.Browsetoanimage file,selectit,andclickOK.Ifyoudon 9thaveanimagefilehandy,try usingonefromthe Windows directory,suchas winnt256.bmp (whichis included with most versions of Windows). Bydefault,theresourcenamehasthesamenameasthefile,butyoucan renameitafteraddingit.Inthisexample,renametheimageto EmbeddedGraphic (as shown in Figure2-2).<br><br> Usingaresourceiseasy.Allresourcesarecompileddynamicallyintoa stronglytypedresourceclass,whichyoucanaccessthrough My. Resources .Totryoutthisresource,adda PictureBox controltoyour Windowsform(andkeepthedefaultname PictureBox1 ).Then,addthe following code to show the image when the form loads: Private Sub Form1_Load(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.Load PictureBox1.Image = My.Resources.EmbeddedGraphic End Sub Figure2-2. Adding a picture as a strongly typed resource Theresourcesclass is added in the My Project directory and is given the name Resources.Designer.<br><br> vb. To see it, you need to choose Project  ShowAll Files. Of course, you should never change this file by hand.<br><br> ,ch02.11378 Page 34 Thursday, April 21, 2005 1:32 PM Use Strongly Typed Configuration Settings35 Ifyourunthecode,you 9llseetheimageappearontheform.Tomake suretheimageisbeingextractedfromtheassembly,trycompilingthe applicationandthendeletingtheimagefile(thecodewillstillwork seamlessly). Whenyouaddaresourceinthisway,VisualStudiocopiestheresource tothe Resources subdirectoryofyourapplication.Youcanseethisdirec- tory,alongwithalltheresourcesitcontains,intheSolutionExplorer. Whenyoucompileyourapplication,alltheresourcesareembeddedin theassembly.However,there 9sadistinctadvantagetomaintainingthem inaseparatedirectory.Thisway,youcaneasilyupdatearesourceby replacingthefileandrecompilingtheapplication.Youdon 9tneedto modifyanycode.Thisisatremendousbenefitifyouneedtoupdatea number of images or other resources at once.<br><br> YoucanalsoattacharesourcetovariouscontrolsusingtheProperties window.Forexample,whenyouclicktheellipsis(&)intheProperties windownexttothe Image propertyforthe PictureBox control,adesigner appearsthatlistsallthepicturesthatareavailableintheapplication 9s resources. What about... &the ImageList ?Ifyou 9reaWindowsdeveloper,you 9reprobablyfamil- iarwiththe ImageList control,whichgroupstogethermultipleimages (usuallysmallbitmaps)foruseinothercontrols,suchasmenus,toolbars, trees,andlists.The ImageList doesn 9tusetypedresources.Instead,it usesacustomserializationscheme.You 9llfindthatalthoughthe ImageList providesdesign-timesupportandprogrammaticaccesstothe images it contains, this access isn 9t strongly typed.<br><br> Use Strongly Typed Con;guration Settings Applicationscommonlyneedconfigurationsettingstonaildowndetails likefilelocations,databaseconnectionstrings,anduserpreferences. Ratherthanhardcodingthesesettings(orinventingyourownmecha- nismtostorethem),.NETletsyouaddthemtoanapplication-specific configurationfile.Thisallowsyoutoadjustvaluesonawhimbyediting a text file without recompiling your application. InVisualStudio2005,configurationsettingsareeveneasiertouse.<br><br> That 9sbecausethey 9reautomaticallycompiledintoacustomclassthat providesstronglytypedaccesstothem.Thatmeansyoucanretrieve Ano t her advantage of resources is that you can use the same images in multiple controls on multiple different forms, without needing toaddmorethan one copy of the same file. Use error-proof configuration settings by the application designer. ,ch02.11378 Page 35 Thursday, April 21, 2005 1:32 PM 36Chapter2:The Visual Basic Language settingsusingproperties,withthehelpofIntelliSense,insteadofrelying onstring-basedlookups.Evenbetter,.NETenhancesthismodelwiththe abilitytouseupdatable,user-specificsettingstotrackpreferencesand other information.<br><br> You 9ll see both of these techniques at work in this lab. How do I do that? Everycustomconfigurationsettingisdefinedwithauniquestringname.<br><br> Inpreviousversionsof.NET,youcouldretrievethevalueofaconfigura- tionsettingbylookingupthevaluebyitsstringnameinacollection. However,ifyouusethewrongname,youwouldn 9trealizeyourerror until you run the code and it fails with a runtime exception. InVisualStudio2005,thestoryismuchimproved.Toaddanewconfig- urationsetting,double-clicktheMyProjectnodeintheSolutionExplorer.<br><br> Thisopensuptheapplicationdesignerwhereyoucanconfigureahostof application-relatedsettings.Next,clicktheSettingstab,whichshowsa listofcustomconfigurationsettingswhereyoucandefinenewsettings and their values. Toaddacustomconfigurationsettingtoyourapplication,enteranew settingnameatthebottomofthelist.Thenspecifythedatatype,scope, andtheactualcontentofthesetting.Forexample,toaddasettingwitha filepath,youmightusethename UserDataFilePath ,thetype String , thescope Application (you 9lllearnmoreaboutthisshortly),andthe value c:\MyFiles . Figure2-3 shows this setting.<br><br> Figure2-3. Defining a strongly typed application setting I n a web applica- tion,configuration settings are p laced in the web. config file.<br><br> In other applica- tions, application settings are recorded to a configuration file that takes the name of the application, plus the extension .config, as in MyApp.exe.config. ,ch02.11378 Page 36 Thursday, April 21, 2005 1:32 PM Use Strongly Typed Configuration Settings37 Whenyouaddthesetting,VisualStudio.NETinsertsthefollowinginfor- mation into the application configuration file: <configuration> <!-- Other settings are defined here. --> <applicationSettings> <WindowsApplication1.MySettings> <setting name="UserDataFilePath" serializeAs="String"> <value>c:\MyFiles</value> </setting> </WindowsApplication1.MySettings> </applicationSettings> </configuration> Atthesametimebehindthescenes,VisualStudiocompilesaclassthat includesinformationaboutyourcustomconfigurationsetting.Then, youcanaccessthesettingbynameanywhereinyourcodethroughthe My.Settings object.Forexample,here 9scodethatretrievesthesetting named UserDataFilePath : Dim path As String path = My.Settings.UserDataFilePath In.NET2.0,configurationsettingsdon 9tneedtobestrings.Youcanalso useotherserializabledatatypes,includingintegers,decimals,dates,and times(justchoosetheappropriatedatatypefromtheTypesdrop-down list).Thesedatatypesareserializedtotextintheconfigurationfile,but youcanretrievethemthrough My.Settings astheirnativedatatype, with no parsing required!<br><br> What about... &updatingsettings?TheUserDataFilePathexampleusesan application- scoped setting,whichcanbereadatruntimebutcan 9tbemodified.If youneedtochangeanapplication-scopedsetting,youhavetomodify the configuration file by hand (or use the settings list in Visual Studio). Yourotherchoiceistocreate user-scoped settings.Todothis,just choose User fromtheScopedrop-downlistinthesettingslist.Witha user-scopedsetting,thevalueyousetinVisualStudioisstoredasthe defaultintheconfigurationfileintheapplicationdirectory.However, whenyouchangethesesettings,anew user.config fileiscreatedforthe currentuserandsavedinauser-specificdirectory(withanameinthe form c:\DocumentsandSettings\[UserName]\LocalSettings\Application Data\[ApplicationName]\[UniqueDirectory] ).<br><br> Theonlytrickpertainingtouser-specificsettingsisthatyou must call My.Settings.Save() tostoreyourchanges.Otherwise,changeswillonly T he applica t ion settings class is added in the My P roject directory and is named Settings.Designer. vb. To see it, select Project  Show All Files.<br><br> ,ch02.11378 Page 37 Thursday, April 21, 2005 1:32 PM 38Chapter2:The Visual Basic Language persistuntiltheapplicationisclosed.Typically,you 9llcall My.Settings. Save() when your application ends. Totryoutauser-scopedsetting,changethescopeoftheUserDataFilePath settingfromApplicationtoUser.Then,createaformthathasatextbox (named txtFilePath )andtwobuttons,oneforretrievingtheuserdata ( cmdRefresh )andoneforchangingit( cmdUpdate ).Herearetheeventhan- dlers you 9ll use: Private Sub cmdRefresh_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdRefresh.Click txtFilePath.Text = My.Settings.UserDataFilePath End Sub Private Sub cmdUpdate_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles cmdUpdate.Click My.Settings.UserDataFilePath = txtFilePath.Text End Sub Finally,tomakesureyourchangesaretherethenexttimeyourunthe application,tell.NETtocreateorupdatethe user.config filewhenthe form closes with this code: Private Sub Form1_FormClosed(ByVal sender As Object, _ ByVal e As System.Windows.Forms.FormClosedEventArgs) _ Handles Me.FormClosed My.Settings.Save() End Sub Thisroundsoutasimpletestform.Youcanrunthisapplicationandtry alternatelyretrievingthecurrentsettingandstoringanewone.Ifyou 9re interested,youcanthentrackdownthe user.config filethathasthe changed settings for the current user.<br><br> Build Typesafe Generic Classes Programmersoftenfaceadifficultchoice.Ononehand,it 9skeenly importanttobuildsolutionsthatareasgenericaspossible,sothatthey canbereusedindifferentscenarios.Forexample,whybuilda CustomerCollection classthatacceptsonlyobjectsoftype Customer whenyoucanbuildageneric Collection classthatcanbeconfiguredto acceptobjectsofanytype?Ontheotherhand,performanceandtype safetyconsiderationscanmakeagenericsolutionlessdesirable.Ifyou useageneric.NET Collection classtostore Customer objects,forexam- ple,howcanyoubesurethatsomeonewon 9taccidentallyinsertanother type of object into the collection, causing an insidious problem later on? VisualBasic2005and.NET2.0provideasolutioncalled generics . Genericsareclassesthatare parameterizedbytype .Inotherwords, N eed t o crea t e a class that 9s f lexible enough to work with any type of object, but able to restrict the objects it accepts in any given instance?<br><br> With generics, VB has the perfect solution. ,ch02.11378 Page 38 Thursday, April 21, 2005 1:32 PM Build Typesafe Generic Classes39 genericsallowyoutocreateaclasstemplatethatsupportsanytype. Whenyouinstantiatethatclass,youspecifythetypeyouwanttouse, and from that point on, your object is clocked in d to the type you chose.<br><br> How do I do that? Anexampleofwheretheuseofgenericsmakesgreatsenseisthe System.Collections.ArrayList class. ArrayList isanall-purpose, dynamicallyself-sizingcollection.Itcanholdordinary.NETobjectsor yourowncustomobjects.Inordertosupportthis, ArrayList treats everything as the base Object type.<br><br> Theproblemisthatthere 9snowaytoimposeanyrestrictionsonhow ArrayList works.Forexample,ifyouwanttouse ArrayList tostorea collectionof Customer objects,youhavenowaytobesurethatafaulty pieceofcodewon 9taccidentallyinsertstrings,integers,orsomeother typeofobject,causingfutureheadaches.Forthisreason,developers oftencreatetheirownstronglytypedcollectionclasses 4infact,the.NET class library is filled with dozens of them. Genericscansolvethisproblem.Forexample,usinggenericsyoucan declare a class that works with any type using the Of keyword: Public Class GenericList (Of ItemType) ' (Code goes here) End Class Inthiscase,youarecreatinganewclassnamed GenericList thatcan workwithanytypeofobject.However,theclientneedstospecifywhat typeshouldbeused.Inyourclasscode,yourefertothattypeas ItemType .Ofcourse, ItemType isn 9treallyatype 4it 9sjustaplaceholder forthetypethatyou 9llchoosewhenyouinstantiatea GenericList object. Example2-2 shows the complete code for a simple typesafe ArrayList .<br><br> Example2-2 . A typesafe collection using generics Public Class GenericList(Of ItemType) Inherits CollectionBase Public Function Add(ByVal value As ItemType) As Integer Return List.Add(value) End Function Public Sub Remove(ByVal value As ItemType) List.Remove(value) End Sub ,ch02.11378 Page 39 Thursday, April 21, 2005 1:32 PM 40Chapter2:The Visual Basic Language The GenericList classwrapsanordinary ArrayList ,whichisprovided throughthe List propertyofthe CollectionBase classitinheritsfrom. However,the GenericList classworksdifferentlythanan ArrayList by providingstronglytyped Add() and Remove() methods,whichusethe ItemType placeholder.<br><br> Here 9sanexampleofhowyoumightusethe GenericList classtocreate an ArrayList collection that only supports strings: ' Create the GenericList instance, and choose a type (in this case, string). Dim List As New GenericList(Of String) ' Add two strings. List.Add("blue") List.Add("green") ' The next statement will fail because it has the wrong type.<br><br> ' There is no automatic way to convert a GUID to a string. ' In fact, this line won't ever run, because the compiler ' notices the problem and refuses to build the application. List.Add(Guid.NewGuid()) There 9snolimittohowmanywaysyoucanparameterizeaclass.Inthe GenericList example,there 9sonlyonetypeparameter.However,you couldeasilycreateaclassthatworkswithtwoorthreetypesofobjects, andallowsyoutomakeallofthesetypesgeneric.Tousethisapproach, justseparateeachparametertypewithacomma(betweenthebrackets at the beginning of a class).<br><br> Forexample,considerthefollowing GenericHashTable class,which allowsyoutodefinethetypeoftheitemsthecollectionwillstore ( ItemType ),aswellasthetypeofthekeysyouwillusetoindexthose items ( KeyType ): Public Class GenericHashTable(Of ItemType, KeyType) Inherits DictionaryBase ' (Code goes here.) End Class Public ReadOnly Property Item(ByVal index As Integer) As ItemType Get ' The appropriate item is retrieved from the List object and ' explicitly cast to the appropriate type, and then returned. Return CType(List.Item(index), ItemType) End Get End Property End Class Example2-2 . A typesafe collection using generics (continued) ,ch02.11378 Page 40 Thursday, April 21, 2005 1:32 PM Build Typesafe Generic Classes41 Anotherimportantfeatureingenericsistheabilitytoapply constraints to parameters.Constraintsrestrictthetypesallowedforagivengeneric class.Forexample,supposeyouwanttocreateaclassthatsupportsonly typesthatimplementaparticularinterface.Todoso,firstdeclarethe typeortypestheclassacceptsandthenusethe As keywordtospecify thebaseclassthatthetypemustderivefrom,ortheinterfacethatthe type must implement.<br><br> Here 9sanexamplethatrestrictstheitemsstoredina GenericList to serializableitems.Thisfeaturewouldbeusefulif,forexample,you wantedtoaddamethodtothe GenericList thatrequiredserialization, such as a method that writes all the items in the list to a stream: Public Class SerializableList(Of ItemType As ISerializable) Inherits CollectionBase ' (Code goes here.) End Class Similarly,here 9sacollectionthatcancontainanytypeofobject,pro- videdit 9sderivedfromthe System.Windows.Forms.Control class.The endresultisacollectionthat 9slimitedtocontrols,liketheoneexposed by the Forms.Controls property on a window: Public Class ControlCollection(Of ItemType As Control) Inherits CollectionBase ' (Code goes here.) End Class Sometimes,yourgenericclassmightneedtheabilitytocreatethe parameterclass.Forexample,the GenericList examplemightneedthe abilitytocreateaninstanceoftheitemyouwanttostoreinthecollec- tion.Inthiscase,youneedtousethe New constraint.The New constraint allowsonlyparametertypesthathaveapubliczero-argumentconstruc- tor,andaren 9tmarked MustInherit .Thisensuresthatyourcodecancre- ateinstancesoftheparametertype.Here 9sacollectionthatimposesthe New constraint: Public Class GenericList(Of ItemType As New) Inherits CollectionBase ' (Code goes here.) End Class It 9salsoworthnotingthatyoucandefineasmanyconstraintsasyou want,aslongasyougroupthelistofconstraintsincurlybraces,as shown here: Public Class GenericList(Of ItemType As {ISerializable, New}) Inherits CollectionBase ' (Code goes here.) End Class ,ch02.11378 Page 41 Thursday, April 21, 2005 1:32 PM 42Chapter2:The Visual Basic Language Constraintsareenforcedbythecompiler,soifyouviolateaconstraint rulewhenusingagenericclass,youwon 9tbeabletocompileyourappli- cation. What about... &usinggenericswithothercodestructures?Genericsdon 9tjustwork withclasses.Theycanalsobeusedinstructures,interfaces,delegates, andevenmethods.Formoreinformation,lookfortheindexentry cgener- ics dintheMSDNHelp.Formorein-depthexamplesofadvancedgeneric techniques,youcanrefertoaMicrosoftwhitepaperat http://www.msdn.<br><br> net/library/en-us/dnvs05/html/vb2005_generics.asp . Incidentally,the.NETFrameworkdesignersarewellawareoftheuseful- nessofgenericcollections,andthey 9vealreadycreatedseveralforyouto useoutofthebox.You 9llfindtheminthenew Systems.Collections. Generic namespace.<br><br> They include: " List (a basic collection like the GenericList example) " Dictionary (aname-valuecollectionthatindexeseachitemwitha key) " LinkedList (alinkedlist,whereeachitempointstothenextitemin the chain) " Queue (a first-in-first-out collection) " Stack (a last-in-first-out collection) " SortedList (aname-valuecollectionthat 9skeptinperpetuallysorted order) Mostofthesetypesduplicateoneofthetypesinthe System.Collections namespace. The old collections remain for backward compatibility. Make Simple Data Types Nullable Withthenewsupportforgenericsthat 9sfoundinthe.NETFramework,a numberofnewfeaturesbecomepossible.Oneofthesefeatures 4generic stronglytypedcollections 4wasdemonstratedinthepreviouslab, cBuild TypesafeGenericClasses. dNowyou 9llseeanotherwaythatgenericscan solve common problems, this time by using the new nullable data types.<br><br> Generics are buil t into the Common LanguageRuntime. That means they are supported in all first-class .NET languages, including C#. Do you need t o represent data that may or may not be present?<br><br> V B .NET 9s new nullable types fill the gap. ,ch02.11378 Page 42 Thursday, April 21, 2005 1:32 PM Make Simple Data Types Nullable43 How do I do that? Anullvalue(identifiedinVisualBasicbythekeyword Nothing ),isaspe- cialflagthatindicatesnodataispresent.Mostdevelopersarefamiliar withnullobjectreferences,whichindicatethattheobjecthasbeen definedbutnotcreated.Forexample,inthefollowingcode,the FileStream containsanullreferencebecauseithasn 9tbeeninstantiated with the New keyword: Dim fs As FileStream If fs Is Nothing ' This is always true because the FileStream hasn't ' been created yet.<br><br> Console.WriteLine("Object contains a null reference.") End If Coredatatypeslikeintegersandstrings can 9t containnullvalues. Numericvariablesareautomaticallyinitializedto 0 .Booleanvariablesare False .Stringvariablesaresettoanemptystring(''")automatically.In fact,evenifyouexplicitlysetasimpledatatypevariableto Nothing in yourcode,itwillautomaticallyreverttotheemptyvalue( 0 , False ,or""), as the following code demonstrates: Dim j As Integer = Nothing If j = 0 Then ' This is always true because there is an ' implicit conversion between Nothing and 0 for integers. Console.WriteLine("Non-nullable integer j = " & j) End If Thisdesignsometimescausesproblems,becausethere 9snowaytodis- tinguishbetweenanemptyvalueandavaluethatwasneversuppliedin thefirstplace.Forexample,imagineyoucreatecodethatneedsto retrievethenumberoftimestheuserhasplacedanorderfromatextfile.<br><br> Lateron,youexaminethisvalue.Theproblemoccursifthisvalueis 0 . Quitesimply,youhavenowaytoknowwhetherthisisvaliddata(the userplacednoorders),oritrepresentsmissinginformation(thesetting couldn 9t be retrieved or the current user isn 9t a registered customer). Thankstogenerics,.NET2.0hasasolution 4a System.Nullable class thatcanwrapanyotherdatatype.Whenyoucreateaninstanceof Nullable youspecifythedatatype.Ifyoudon 9tsetavalue,thisinstance containsanullreference.Youcantestwhetherthisistruebytestingthe Nullable.HasType() method,andyoucanretrievetheunderlyingobject through the Nullable.Value property.<br><br> ,ch02.11378 Page 43 Thursday, April 21, 2005 1:32 PM 44Chapter2:The Visual Basic Language Here 9s the sample code you need to create a nullable integer: Dim i As Nullable(Of Integer) If Not i.HasValue Then ' This is true, because no value has been assigned. Console.WriteLine("i is a null value") End If ' Assign a value. Note that you must assign directly to i, not i.Value.<br><br> ' The i.Value property is read-only, and it always reflects the ' currently assigned object, if it is not Nothing. i = 100 If i.HasValue Then ' This is true, because a value (100) is now present. Console.WriteLine("Nullable integer i = " & i.Value) End If What about...<br><br> &using Nullable withfull-fledgedreferenceobjects?Althoughyoudon 9t needthisability(becausereferencetypescancontainanullreference),it stillgivesyousomeadvantages.Namely,youcanusetheslightlymore readable HasValue() methodinsteadoftestingfor Nothing .Bestofall, youcanmakethischangeseamlessly,becausethe Nullable classhas theremarkableabilitytoallowimplicitconversionsbetween Nullable and the type it wraps. Where can I learn more? Tolearnmoreabout Nullable andhowit 9simplemented,lookupthe cNullable class d index entry in the MSDN Help.<br><br> Use Operators with Custom Objects EveryVBprogrammerisfamiliarwiththearithmeticoperatorsforaddi- tion(+),subtraction(-),division(/),andmultiplication(*).Ordinarily, theseoperatorsarereservedfor.NETnumerictypes,andhavenomean- ingwhenusedwithotherobjects.However,inVB.NET2.0youcanbuild objectsthatsupportalloftheseoperators,aswellastheoperatorsused forlogicaloperationsandimplicitconversion).Thistechniquewon 9t makesenseforbusinessobjects,butitisextremelyhandyifyouneedto modelmathematicalstructuressuchasvectors,matrixes,complexnum- bers, or 4as demonstrated in the following example 4fractions. T ired of using clumsy syntax like ObjA. Subtract(ObjB) to perform simple operationsonyour custom objects?<br><br> With VB 9s support f or operator overloading, you can manipulate your objects as easily as ordinary numbers. ,ch02.11378 Page 44 Thursday, April 21, 2005 1:32 PM Use Operators with Custom Objects45 How do I do that? TooverloadanoperatorinVisualBasic2005,youneedtocreateaspe- cialoperatormethodinyourclass(orstructure).Thismethodmustbe declaredwiththekeywords PublicSharedOperator ,followedbythe symbol for the operator (e.g., + ).<br><br> TIP To overload anoperatorsimplymeanstodefinewhatanoperator doeswhenusedwithaspecifictypeofobject.Inotherwords,when youoverloadthe+operatorforaFractionclass,youtell.NETwhat to do when your code adds two Fraction objects together. Forexample,here 9sanoperatormethodthataddssupportfortheaddi- tion ( + ) operator: Public Shared Operator+(objA As MyClass, objB as MyClass) As MyClass ' (Code goes here.) End Operator Everyoperatormethodacceptstwoparameters,whichrepresenttheval- uesoneithersideoftheoperator.Dependingontheclassandtheopera- tor, order may be important (as it is for division). Onceyou 9vedefinedanoperator,theVBcompilerwillcallyourcode whenitexecutesastatementthatusestheoperatorwithyourclass.For example, the compiler changes code like this: ObjC = ObjA + ObjB into this: ObjC = MyClass.Operator+(ObjA, ObjB) Example2-3showshowyoucanoverloadtheVisualBasicarithmetic operatorsusedtohandle Fraction objects.A Fraction consistsoftwo portions:anumeratorandadenominator(knowncolloquiallyas cthetop partandthebottompart d).The Fraction codeoverloadsthe + , - , * ,and / operators,allowingyoutoperformfractionalcalculationswithoutcon- verting your numbers to decimals and losing precision.<br><br> Example2-3 . Overloading arithmetic operators in the Fraction class Public Structure Fraction ' The two parts of a fraction. Public Denominator As Integer Public Numerator As Integer Public Sub New(ByVal numerator As Integer, ByVal denominator As Integer) ,ch02.11378 Page 45 Thursday, April 21, 2005 1:32 PM 46Chapter2:The Visual Basic Language Me.Numerator = numerator Me.Denominator = denominator End Sub Public Shared Operator +(ByVal x As Fraction, ByVal y As Fraction) _ As Fraction Return Normalize(x.Numerator * y.Denominator + _ y.Numerator * x.Denominator, x.Denominator * y.Denominator) End Operator Public Shared Operator -(ByVal x As Fraction, ByVal y As Fraction) _ As Fraction Return Normalize(x.Numerator * y.Denominator - _ y.Numerator * x.Denominator, x.Denominator * y.Denominator) End Operator Public Shared Operator *(ByVal x As Fraction, ByVal y As Fraction) _ As Fraction Return Normalize(x.Numerator * y.Numerator, _ x.Denominator * y.Denominator) End Operator Public Shared Operator /(ByVal x As Fraction, ByVal y As Fraction) _ As Fraction Return Normalize(x.Numerator * y.Denominator, _ x.Denominator * y.Numerator) End Operator ' Reduce a fraction.<br><br> Private Shared Function Normalize(ByVal numerator As Integer, _ ByVal denominator As Integer) As Fraction If (numerator <> 0) And (denominator <> 0) Then ' Fix signs. If denominator < 0 Then denominator *= -1 numerator *= -1 End If Dim divisor As Integer = GCD(numerator, denominator) numerator \= divisor denominator \= divisor End If Return New Fraction(numerator, denominator) End Function ' Return the greatest common divisor using Euclid's algorithm. Private Shared Function GCD(ByVal x As Integer, ByVal y As Integer) _ As Integer Dim temp As Integer x = Math.Abs(x) y = Math.Abs(y) Example2-3 .<br><br> Overloading arithmetic operators in the Fraction class (continued) ,ch02.11378 Page 46 Thursday, April 21, 2005 1:32 PM Use Operators with Custom Objects47 TheconsolecodeshowninExample2-4putsthefractionclassthrougha quirk-and-dirtytest.Thankstooperatoroverloading,thenumberremains in fractional form, and precision is never lost. Do While (y <> 0) temp = x Mod y x = y y = temp Loop Return x End Function ' Convert the fraction to decimal form. Public Function GetDouble() As Double Return CType(Me.Numerator, Double) / _ CType(Me.Denominator, Double) End Function ' Get a string representation of the fraction.<br><br> Public Overrides Function ToString() As String Return Me.Numerator.ToString & "/" & Me.Denominator.ToString End Function End Structure Example2-4 . Testing the Fraction class Module FractionTest Sub Main() Dim f1 As New Fraction(2, 3) Dim f2 As New Fraction(1, 4) Console.WriteLine("f1 = " & f1.ToString()) Console.WriteLine("f2 = " & f2.ToString()) Dim f3 As Fraction f3 = f1 + f2 ' f3 is now 11/12 Console.WriteLine("f1 + f2 = " & f3.ToString()) f3 = f1 / f2 ' f3 is now 8/3 Console.WriteLine("f1 / f2 = " & f3.ToString()) f3 = f1 - f2 ' f3 is now 5/12 Console.WriteLine("f1 - f2 = " & f3.ToString()) f3 = f1 * f2 ' f2 is now 1/6 Console.WriteLine("f1 * f2 = " & f3.ToString()) End Sub End Module Example2-3 . Overloading arithmetic operators in the Fraction class (continued) ,ch02.11378 Page 47 Thursday, April 21, 2005 1:32 PM 48Chapter2:The Visual Basic Language When you run this application, here 9s the output you 9ll see: f1 = 2/3 f2 = 1/4 f1 + f2 = 11/12 f1 / f2 = 8/3 f1 - f2 = 5/12 f1 * f2 = 1/6 Usually,theparametersandthereturnvalueofanoperatormethoduse thesametype.However,there 9snoreasonyoucan 9tcreatemorethan oneversionofanoperatormethodsoyourobjectcanbeusedinexpres- sions with different types.<br><br> What about... &usingoperatoroverloadingwithothertypes?Thereareanumberof classesthatarenaturalcandidatesforoperatoroverloading.Hereare some good examples: "Mathematicalclassesthatmodelvectors,matrixes,complexnum- bers, or tensors. "Moneyclassesthatroundcalculationstothenearestpenny,andsup- port different currency types.<br><br> "Measurement classes that have irregular units, like inches and feet. Where can I learn more? Formoreofthelanguagedetailsbehindoperatoroverloadingandallthe operatorsthatyoucanoverload,refertothe cOperatorprocedures dindex entry in the MSDN Help.<br><br> Split a Class into Multiple Files Ifyou 9vecrackedopena.NET2.0WindowsFormsclass,you 9llhave noticedthatalltheautomaticallygeneratedcodeismissing!Tounder- standwhereit 9sgone,youneedtolearnaboutanewfeaturecalled par- tial classes , which allow you to split classes into several pieces. How do I do that? Usingthenew Partial keyword,youcansplitasingleclassintoas manypiecesasyouwant.Yousimplydefinethesameclassinmorethan oneplace.Here 9sanexamplethatdefinesaclassnamed SampleClass in two pieces: Have your classes growntoolargeto manage in one f ile?<br><br> With the new Partial k eyword, you can split a class into separate files. ,ch02.11378 Page 48 Thursday, April 21, 2005 1:32 PM Split a Class into Multiple Files49 Partial Public Class SampleClass Public Sub MethodA() Console.WriteLine("Method A called.") End Sub End Class Partial Public Class SampleClass Public Sub MethodB() Console.WriteLine("Method B called.") End Sub End Class Inthisexample,thetwodeclarationsareinthesamefile,oneafterthe other.However,there 9snoreasonthatyoucan 9tputthetwo SampleClass piecesindifferentsourcecodefilesinthesameproject.(Theonlyrestric- tionsarethatyoucan 9tdefinethetwopiecesinseparateassembliesor in separate namespaces.) Whenyoubuildtheapplicationcontainingthepreviouscode,VisualStu- diowilltrackdowneachpieceof SampleClass andassembleitintoa complete,compiledclasswithtwomethods, MethodA() and MethodB() . You can use both methods, as shown here: Dim Obj As New SampleClass() Obj.MethodA() Obj.MethodB() Partialclassesdon 9tofferyoumuchhelpinsolvingprogrammingprob- lems,buttheycanbeusefulinbreakingupextremelylarge,unwieldy classes.Ofcourse,theexistenceoflargeclassesinyourapplicationcould beasignthatyouhaven 9tproperlyfactoredyourproblem,inwhichcase youshouldreallybreakyourclassdownintoseparate,notpartial, classes.Oneofthekeyrolesofpartialclassesin.NETistohidethe designercodethatisautomaticallygeneratedbyVisualStudio,whose visibilityinpreviousversionshasbeenasourceofannoyancetosome VB programmers.<br><br> Forexample,whenyoubuilda.NETWindowsforminVisualBasic2005, youreventhandlingcodeisplacedinthesourcecodefilefortheform, butthedesignercodethatcreatesandconfigureseachcontrolandcon- nectsitseventhandlersisnowheretobeseen.Inordertoseethiscode, youneedtoselectProject  ShowAllFilesfromtheVisualStudiomenu. Whenyoudo,thefilethatcontainsthemissinghalfoftheclassappears intheSolutionExplorerasaseparatefile.GivenaformnamedForm1, you 9llactuallywindupwitha Form1.vb filethatcontainsyourcodeand a Form1.Designer.vb file that contains the automatically generated part. ,ch02.11378 Page 49 Thursday, April 21, 2005 1:32 PM 50Chapter2:The Visual Basic Language What about...<br><br> &usingthe Partial keywordwithstructures?Thatworks,butyoucan 9t createpartialinterfaces,enumerations,oranyother.NETprogramming construct. Where can I learn more? Togetmoredetailsonpartialclasses,refertotheindexentry cPartial keyword d in the MSDN Help.<br><br> Extend the My Namespace The My objectsaren 9tdefinedinasingleplace.Somecomefromclasses definedinthe Microsoft.VisualBasic.MyServices namespace,while othersaregenerateddynamicallyasyouaddforms,webservices,con- figurationsettings,andembeddedresourcestoyourproject.However,as adeveloperyoucanparticipateinthe My namespaceandextenditwith yourowningredients(e.g.,usefulcalculationsandtasksthatarespecific to your application). How do I do that? Topluganewclassintothe My objecthierarchy,simplyusea Namespace blockwiththename My .Forexample,youcouldaddthiscodetocreatea new BusinessFunctions classthatcontainsacompany-specificfunction forgeneratingcustomidentifiers(byjoiningthecustomernametoanew GUID): Namespace My Public Class BusinessFunctions Public Shared Function GenerateNewCustomerID( _ ByVal name As String) As String Return name & "_" & Guid.NewGuid.ToString() End Function End Class End Namespace Onceyou 9vecreatedthe BusinessFunctions objectintherightplace,you canmakeuseofitinyourapplicationjustlikeanyother My object.For example, to display a new customer ID: Console.WriteLine(My.BusinessFunctions.GenerateNewCustomerID("matthew")) Do you use t he My objects so much you 9d like to customize them yourself?<br><br> VB 2005 lets you plug in your own classes. ,ch02.11378 Page 50 Thursday, April 21, 2005 1:32 PM Extend the My Namespace51 Notethatthe My classesyouaddneedtousesharedmethodsandprop- erties.That 9sbecausethe My objectwon 9tbeinstantiatedautomatically. Asaresult,ifyouuseordinaryinstancemembers,you 9llneedtocreate the My objectonyourown,andyouwon 9tbeabletomanipulateitwith thesamesyntax.Anothersolutionistocreateamoduleinthe My namespace,becauseallthemethodsandpropertiesinamoduleare always shared.<br><br> Youcanalsoextendsomeoftheexisting My objectsthankstopartial classes.Forexample,usingthisfeatureyoucouldaddnewinformationto the My.Computer objectornewroutinestothe My.Application object.In thiscase,theapproachisslightlydifferent. My.Computer exposesan instanceofthe MyComputer object. My.Application exposesaninstance ofthe MyApplication object.Thus,toaddtoeitheroftheseclasses,you needtocreateapartialclasswiththeappropriatename,andaddthe instancemembersyouneed.Youshouldalsodeclarethisclasswiththe accessibility keyword Friend in order to match the existing class.<br><br> Here 9sanexampleyoucanusetoextend My.Application withamethod that checks for update versions: Namespace My Partial Friend Class MyApplication Public Function IsNewVersionAvailable() As Boolean ' Usually, you would read the latest available version number ' from a web service or some other resource. ' Here, it's hardcoded. Dim LatestVersion As New Version(1, 2, 1, 1) Return Application.Info.Version.CompareTo(LatestVersion) End Function End Class End Namespace And now you can use this method: If My.Application.IsNewVersionAvailable() Console.WriteLine("A newer version is available.") Else Console.WriteLine("This is the latest version.") End If What about...<br><br> &usingyour My extensionsinmultipleapplications?There 9snoreason youcan 9ttreat My classesinthesamewaythatyoutreatanyotheruse- fulclassthatyouwanttoreuseinmultipleapplications.Inotherwords, Shared members aremembersthat are always available through the class name, evenifyouhaven 9t created an object. If you use shared variables, there will be one copy of that variable, which is global to your whole application. ,ch02.11378 Page 51 Thursday, April 21, 2005 1:32 PM 52Chapter2:The Visual Basic Language youcancreateaclasslibraryproject,addsome My extensions,andcom- pile it to a DLL.<br><br> You can then reference that DLL in other applications. Ofcourse,despitewhatMicrosoftenthusiastsmaytellyou,extendingthe My namespace in that way has two potentially dangerous drawbacks: "Itbecomesmoreawkwardtoshareyourcomponentwithotherlan- guages.Forexample,C#doesnotprovidea My feature.Althoughyou couldstilluseacustom My objectinaC#application,itwouldn 9tplug in as neatly. "Whenyouusethe My namespace,youcircumventoneofthegreat benefitsofnamespaces 4avoidingnamingconflicts.Forexample, considertwocompanieswhocreatecomponentsforlogging.Ifyou usetherecommended.NETnamespacestandard( CompanyName.<br><br> ApplicationName.ClassName ),there 9slittlechancethesetwocompo- nentswillhavethesamefullyqualifiednames.Onemightbe Acme. SuperLogger.Logger whiletheotheris ComponentTech.LogMagic. Logger .However,iftheybothextenda My object,it 9squitepossible thattheywouldbothusethesamename(like My.Application.<br><br> Logger ).Asaresult,youwouldn 9tbeabletousebothoftheminthe same application. Skip to the Next Iteration of a Loop TheVisualBasiclanguageprovidesahandfulofcommon flowcontrol statements,whichletyoudirecttheexecutionofyourcode.Forexam- ple,youcanuse Return tostepoutofafunction,or Exit tobackoutofa loop.However,beforeVB2005,therewasn 9tanywaytoskiptothenext iteration of a loop. How do I do that?<br><br> The Continue statementisoneofthoselanguagedetailsthatseemslike aminorfrillatfirst,butquicklyprovesitselftobeamajorconvenience. The Continue statementexistsinthreeversions: ContinueFor , Continue Do ,and ContinueWhile ,eachofwhichisusedwithadifferenttypeof loop ( For & Next , Do & Loop , or While & End While ). To see how the Continue statement works consider the following code: For i = 1 to 1000 If i Mod 5 = 0 Then ' (Task A code.) V B 9snewCon t inue k eyword gives you a quick way to step out of a tangled block of codeinaloopand head straight into the next iteration.<br><br> ,ch02.11378 Page 52 Thursday, April 21, 2005 1:32 PM Skip to the Next Iteration of a Loop53 Continue For End If ' (Task B code.) Next Thiscodeloops1,000times,incrementingacounter i .Whenever i is divisiblebyfive,thetaskAcodeexecutes.Then,the ContinueFor state- mentisexecuted,thecounterisincremented,andexecutionresumesat the beginning of the loop, skipping the code in task B. Inthisexample,thecontinuestatementisn 9treallyrequired,becauseyou could rewrite the code easily enough as follows: For i = 1 to 1000 If i Mod 5 = 0 Then ' (Task A code.) Else ' (Task B code.) End If Next However,thisisn 9tnearlyaspossibleifyouneedtoperformseveraldif- ferenttests.Toseetherealbenefitofthe Continue statement,youneed to consider a more complex (and realistic) example. Example2-5demonstratesaloopthatscansthroughanarrayofwords.<br><br> Eachwordisanalyzed,andtheprogramdecideswhetherthewordis madeupofletters,numericcharacters,orthespacecharacter.Ifthepro- grammatchesonetest(forexample,thelettertest),itneedstocontinue tothenextwordwithoutperformingthenexttest.Toaccomplishthis withoutusingthe Continue statement,youneedtousenestedloops,an approach that creates awkward code. Example2-5 . Analyzing a string without using the Continue statement ' Define a sentence.<br><br> Dim Sentence As String = "The final number is 433." ' Split the sentence into an array of words. Dim Delimiters() As Char = {" ", ".", ","} Dim Words() As String = Sentence.Split(Delimiters) ' Examine each word. For Each Word As String In Words ' Check if the word is blank.<br><br> If Word <> "" Then Console.Write("'" + Word + "'" & vbTab & "= ") ' Check if the word is made up of letters. Dim AllLetters As Boolean = True For Each Character As Char In Word If Not Char.IsLetter(Character) Then ,ch02.11378 Page 53 Thursday, April 21, 2005 1:32 PM 54Chapter2:The Visual Basic Language Now,considertherewrittenversionshowninExample2-6thatusesthe Continue statement to clarify what 9s going on. AllLetters = False End If Next If AllLetters Then Console.WriteLine("word") Else ' If the word isn't made up of letters, ' check if the word is made up of numbers.<br><br> Dim AllNumbers As Boolean = True For Each Character As Char In Word If Not Char.IsDigit(Character) Then AllNumbers = False End If Next If AllNumbers Then Console.WriteLine("number") Else ' If the word isn't made up of letters or numbers, ' assume it's something else. Console.WriteLine("mixed") End If End If End If Next Example2-6 . Analyzing a string using the Continue statement ' Examine each word.<br><br> For Each Word As String In Words ' Check if the word is blank. If Word = "" Then Continue For Console.Write("'" + Word + "'" & vbTab & "= ") ' Check if the word is made up of letters. Dim AllLetters As Boolean = True For Each Character As Char In Word If Not Char.IsLetter(Character) Then AllLetters = False End If Next If AllLetters Then Console.WriteLine("word") Continue For End If ' If the word isn't made up of letters, ' check if the word is made up of numbers.<br><br> Dim AllNumbers As Boolean = True For Each Character As Char In Word Example2-5 . Analyzing a string without using the Continue statement (continued) ,ch02.11378 Page 54 Thursday, April 21, 2005 1:32 PM Dispose of Objects Automatically55 What about... &using Continue inanestedloop?It 9spossible.Ifyounesta For loop insidea Do loop,youcanuse ContinueFor toskiptothenextiterationof theinnerloop,or ContinueDo toskiptothenextiterationoftheouter loop.Thistechniquealsoworksinreverse(witha Do loopinsidea For loop),butitdoesn 9tworkifyounestaloopinsideanotherloopofthe sametype.Inthiscase,there 9snounambiguouswaytorefertotheouter loop, and so your Continue statement always refers to the inner loop.<br><br> Where can I learn more? Forthelanguagelowdownon Continue ,refertotheindexentry ccon- tinue statement d in the MSDN Help. Dispose of Objects Automatically In.NET,it 9skeenlyimportanttomakesureobjectsthatuseunmanaged resources(e.g.,filehandles,databaseconnections,andgraphicscon- texts)releasetheseresourcesassoonaspossible.Towardthisend,such objectsshouldalwaysimplementthe IDisposable interface,andprovide a Dispose() methodthatyoucancalltoreleasetheirresourcesimmedi- ately.<br><br> Theonlyproblemwiththistechniqueisthatyoumustalwaysremember tocallthe Dispose() method(oranothermethodthatcalls Dispose() , suchasa Close() method).VB2005providesanewsafeguardyoucan apply to make sure Dispose() is always called: the Using statement. If Not Char.IsDigit(Character) Then AllNumbers = False End If Next If AllNumbers Then Console.WriteLine("number") Continue For End If ' If the word isn't made up of letters or numbers, ' assume it's something else. Console.WriteLine("mixed") Next Example2-6 .<br><br> Analyzing a string using the Continue statement (continued) Worried t ha t you 9ll have objects f loatingaroundin memory, tying up resourcesuntilthe garbage collector tracks them down? With the Using statement, you can make sure disposableobjects meet with a timely demise. ,ch02.11378 Page 55 Thursday, April 21, 2005 1:32 PM 56Chapter2:The Visual Basic Language How do I do that?<br><br> Youusethe Using statementinablockstructure.Inthefirstline,when youdeclarethe Using block,youspecifythedisposableobjectyouare using.Often,you 9llalsocreatetheobjectatthesametimeusingthe New keyword.Then,youwritethecodethatusesthedisposableobjectinside the Using block.Here 9sanexamplewithasnippetofcodethatcreatesa new file and writes some data to the file: Using NewFile As New System.IO.StreamWriter("c:\MyFile.txt") NewFile.WriteLine("This is line 1") NewFile.WriteLine("This is line 2") End Using ' The file is closed automatically. ' The NewFile object is no longer available here. Inthisexample,assoonastheexecutionleavesthe Using block,the Dispose() methodiscalledonthe NewFile object,releasingthefile handle.<br><br> What about... &errorsthatoccurinsidea Using block?Thankfully,.NETmakessureit disposesoftheresourcenomatterhowyouexitthe Using block,evenif an unhandled exception occurs. The Using statementmakessensewithallkindsofdisposableobjects, such as: "Files (including FileStream , StreamReader , and StreamWriter ) "Databaseconnections(including SqlConnection , OracleConnection , and OleDbConnection ) "Networkconnections(including TcpClient , UdpClient , NetworkStream , FtpWebResponse , HttpWebResponse ) "Graphics (including Image , Bitmap , Metafile , Graphics ) Where can I learn more?<br><br> Forthelanguagelowdown,refertotheindexentry cUsingblock dinthe MSDN Help. ,ch02.11378 Page 56 Thursday, April 21, 2005 1:32 PM Safeguard Properties with Split Accessibility57 Safeguard Properties with Split Accessibility Mostpropertiesconsistofa propertygetprocedure (whichallowsyouto retrievethepropertyvalue)anda propertysetprocedure (whichallows youtosetanewvaluefortheproperty).InpreviousversionsofVisual Basic,thedeclaredaccesslevelofbothproceduresneededtobethe same.InVB2005,youcanprotectapropertybyassigningtothesetpro- cedure a lower access level than you give to the get procedure. How do I do that?<br><br> VBrecognizesthreelevelsofaccessibility.Arrangedfrommosttoleast permissive, these are: " Public (available to all classes in all assemblies) " Friend (available to all code in all the classes in the current assembly) " Private (only available to code in the same class) ImagineyouarecreatingaDLLcomponentthat 9sgoingtobeusedby anotherapplication.Youmightdecidetocreateapropertycalled Status thattheclientapplicationneedstoread,andsoyoudeclaretheprop- erty Public : Public Class ComponetClass Private _Status As Integer Public Property Status() As Integer Get Return _Status End Get Set(ByVal value As Integer) _Status = value End Set End Property End Class Theproblemhereisthattheaccesslevelassignedtothe Status property allowstheclienttochangeit,whichdoesn 9tmakesense.Youcouldmake Status aread-onlyproperty(inotherwords,omitthepropertysetproce- durealtogether),butthatwouldn 9tallowotherclassesthatarepartof your applications and located in your component assembly to change it. I n t he pas t , there was no way to create a p roperty that everyone could readbutonlyyour application could update. VB 2005 f inallyloosensthe rulesandgivesyou more flexibility.<br><br> ,ch02.11378 Page 57 Thursday, April 21, 2005 1:32 PM 58Chapter2:The Visual Basic Language Thesolutionistogivethepropertysetprocedurethe Friend accessibil- itylevel.Here 9swhatthecodeshouldlooklike,withtheonlychange highlighted: Public Property Status() As Integer Get Return _Status End Get Friend Set(ByVal value As Integer) _Status = value End Set End Property What about... &read-onlyandwrite-onlyproperties?Splitaccessibilitydoesn 9thelp youifyouneedtomakearead-onlyproperty(suchasacalculatedvalue) orawrite-onlyvalue(suchasapasswordthatshouldn 9tremainaccessi- ble).Tocreatearead-onlyproperty,addthe ReadOnly keywordtothe propertydeclaration(rightaftertheaccessibilitykeyword),andremove thepropertysetprocedure.Tocreateawrite-onlyproperty,removethe propertygetprocedureandaddthe WriteOnly keyword.Thesekeywords are nothing new 4they 9ve been available since Visual Basic .NET 1.0. Evaluate Conditions Separately with Short-Circuit Logic InpreviousversionsofVB,thereweretwologicaloperators: And and Or .<br><br> VisualBasic2005introducestwonewoperatorsthatsupplementthese: AndAlso and OrElse .Theseoperatorsworkinthesamewayas And and Or ,excepttheyhavesupportforshort-circuiting,whichallowsyouto evaluate just one part of a long conditional statement. How do I do that? Acommonprogrammingscenarioistheneedtoevaluateseveralcondi- tionsinarow.Often,thisinvolvescheckingthatanobjectisnotnull, andthenexaminingoneofitsproperties.Inordertohandlethissce- nario, you need to use nested If blocks, as shown here: If MyObject Is Nothing Then If MyObject.Value > 10 Then ' (Do something.) End If End If Wi t h shor t - circuiting, you can combine multiple conditions to write more compact code.<br><br> ,ch02.11378 Page 58 Thursday, April 21, 2005 1:32 PM Evaluate Conditions Separately with Short-Circuit Logic59 Itwouldbenicetocombinebothoftheseconditionsintoasingleline,as follows: If MyObject Is Nothing And MyObject.Value > 10 Then ' (Do something.) End If Unfortunately,thiswon 9tworkbecauseVBalwaysevaluatesbothcondi- tions.Inotherwords,evenif MyObject is Nothing ,VBwillevaluatethe secondconditionandattempttoretrievethe MyObject.Value property, which will cause a NullReferenceException . VisualBasic2005solvesthisproblemwiththe AndAlso and OrElse key- words.Whenyouusethesekeywords,VisualBasicwon 9tevaluatethe second condition if the first condition is false. Here 9s the corrected code: If MyObject Is Nothing AndAlso MyObject.Value > 10 Then ' (Do something.) End If What about...<br><br> &otherlanguagerefinements?Inthischapter,you 9vehadatourofthe mostimportantVBlanguageinnovations.However,it 9sworthpointing outafewofthelesssignificantonesthatIhaven 9tincludedinthis chapter: "The IsNot keywordallowsyoutosimplifyawkwardsyntaxslightly. Usingit,youcanreplacesyntaxlike IfNotxIsNothing withthe equivalent statement If x IsNot Nothing . "The TryCast() functionallowsyoutoshaveafewmillisecondsoff typecastingcode.Itworkslike CType() or DirectCast() ,withone exception 4iftheobjectcan 9tbeconvertedtotherequestedtypea nullreferenceisreturnedinstead.Thus,insteadofcheckingan object 9stypeandthencastingit,youcanuse TryCast() rightaway and then check if you have an actual object instance.<br><br> "Unsignedintegersallowyoutostorenumericvaluesthatcan 9tbe negative.Thatrestrictionsavesonmemorystorage,allowingyouto accommodatelargernumbers.Unsignednumbershavealwaysbeen inthe.NETFramework,butnowVB2005includeskeywordsfor them ( UInteger , ULong , and UShort ). ,ch02.11378 Page 59 Thursday, April 21, 2005 1:32 PM

less

Copyright © 2010 beepdf.com. All rights reserved.