Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 92 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
92
Dung lượng
1,1 MB
Nội dung
Chapter 12: Advanced Object - Oriented Techniques 427 End If ‘If the user can see us, hide us If Me.Visible = True Then Me.Visible = False End Sub 11. Run the project, and the icon will appear on the system tray. Right - click the icon, and you ’ ll see a list of favorites as was shown in Figure 12 - 7 . Clicking one opens Internet Explorer; clicking Exit closes the application. How It Works One thing to note is that, because of the order of events that are fired for your form, you have to create a variable in Form1 called blnLoadCalled . This variable makes sure that your favorites get loaded in the form ’ s Load event. The WebFavoriteMenuItem class accepts a WebFavorite object in its constructor, and it configures itself as a menu item using the class. However, this class provides a Click method that you can overload. So, when the user selects the item from the menu, you can immediately open the URL: Private Sub WebFavoriteMenuItem_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Click ‘Open the favorite If Not Favorite Is Nothing Then Process.Start(Favorite.Url) End If End Sub The ExitMenuItem class does a similar thing. When this item is clicked, you call the shared Application.Exit method to quit the program: Private Sub ExitMenuItem_Click(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Click Application.Exit() End Sub The important thing here is not the construction of the application itself but rather the fact that you can reuse the functionality you built in a different project. This underlines the fundamental motive for reuse; it means you don ’ t have to reinvent the wheel every time you want to do something. The method of reuse described here was to add the existing classes to your new project, hence making a second copy of them. This isn ’ t efficient, because it takes double the amount of storage needed for the classes; however, the classes are small, so the cost of memory is minimal. It did save you from having to create the classes from scratch, allowing you to reuse the existing code, and it was very easy to do. An alternative way of reusing classes is to create them in a class library. This class library is a separate project that can be referenced by a number of different applications so that only one copy of the code is required. This is discussed in Chapter 13 . c12.indd 427c12.indd 427 4/1/08 6:36:19 PM4/1/08 6:36:19 PM Chapter 12: Advanced Object - Oriented Techniques 428 Using Shared Properties and Methods On occasion, you might find it useful to access methods and properties that are not tied to an instance of an object but are still associated with a class. Imagine you have a class that stores the user name and password of a user for a computer program. You might have something that looks like this: Public Class User ‘Public members Public Username As String ‘Private members Private strPassword As String End Class Now imagine that the password for a user has to be of a minimum length. You create a separate member to store the length and implement a property like this: Public Class User ‘Public members Public Username As String Public MinPasswordLength As Integer = 6 ‘Private members Private strPassword As String ‘Password property Public Property Password() As String Get Return strPassword End Get Set(ByVal value As String) If value.Length > = MinPasswordLength Then strPassword = value End If End Set End Property End Class That seems fairly straightforward. But now imagine that you have five thousand user objects in memory. Each MinPasswordLength variable takes up 4 bytes of memory, meaning that 20 KB of memory is being used to store the same value. Although 20 KB of memory isn ’ t a lot for modern computer systems, it ’ s extremely inefficient, and there is a better way. Using Shared Procedures Ideally, you want to store the value for the minimum password length in memory against a specific class once and share that memory between all of the objects created from that class, as you ’ ll do in the following Try It Out. c12.indd 428c12.indd 428 4/1/08 6:36:19 PM4/1/08 6:36:19 PM Chapter 12: Advanced Object - Oriented Techniques 429 Try It Out Using Shared Properties 1. Close the existing solution if it is still open and create a new Windows Forms Application project called Shared Demo . 2. When the Designer for Form1 appears, change the Text property of the form to Shared Demo and then drag a ListBox, a Label, and a NumericUpDown control from the Toolbox onto the form and arrange them as shown in Figure 12 - 9 . Figure 12 - 9 3. Set the Name property of the ListBox control to lstUsers . 4. Set the Name property of the NumericUpDown control to nudMinPasswordLength , set the Maximum property to 10 , and set the Value property to 6 . 5. Using the Solution Explorer, create a new class named User . Add the highlighted code to the class: Public Class User ‘Public members Public Username As String Public Shared MinPasswordLength As Integer = 6 ‘Private members Private strPassword As String ‘Password property Public Property Password() As String Get Return strPassword End Get Set(ByVal value As String) If value.Length > = MinPasswordLength Then strPassword = value End If End Set End Property End Class c12.indd 429c12.indd 429 4/1/08 6:36:19 PM4/1/08 6:36:19 PM Chapter 12: Advanced Object - Oriented Techniques 430 6. View the code for Form1 and add this highlighted member: Public Class Form1 ‘Private member Private arrUserList As New ArrayList() 7. Add this method to the Form1 class: Private Sub UpdateDisplay() ‘Clear the list lstUsers.Items.Clear() ‘Add the users to the list box For Each objUser As User In arrUserList lstUsers.Items.Add(objUser.Username & “, “ & objUser.Password & _ “ (“ & User.MinPasswordLength & “)”) Next End Sub 8. Select (Form1 Events) in the Class Name combo box at the top of the Code Editor and the Load event in the Method Name combo box. Add the highlighted code to the Load event: Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load ‘Load 100 users For intIndex As Integer = 1 To 100 ‘Create a new user Dim objUser As New User objUser.Username = “Stephanie” & intIndex objUser.Password = “password15” ‘Add the user to the array list arrUserList.Add(objUser) Next ‘Update the display UpdateDisplay() End Sub 9. Select nudMinPasswordLength in the Class Name combo box at the top of the Code Editor and the ValueChanged event in the Method Name combo box. Add the highlighted code to the ValueChanged event: Private Sub nudMinPasswordLength_ValueChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles nudMinPasswordLength.ValueChanged ‘Set the minimum password length User.MinPasswordLength = nudMinPasswordLength.Value ‘Update the display UpdateDisplay() End Sub c12.indd 430c12.indd 430 4/1/08 6:36:19 PM4/1/08 6:36:19 PM Chapter 12: Advanced Object - Oriented Techniques 431 10. Save your project by clicking the Save All button on the toolbar. 11. Run the project. You should see a screen like the one shown in Figure 12 - 10 . Figure 12 - 10 12. Scroll the NumericUpDown control up or down, and the list updates and the number in parentheses changes to correspond to the number shown in the NumericUpDown control. How It Works To create a member variable, property, or method on an object that is shared, you use the Shared keyword. Public Shared MinPasswordLength As Integer = 6 This tells Visual Basic 2008 that the item should be available to all instances of the class. Shared members can be accessed from within nonshared properties and methods as well as from shared properties and methods. For example, here ’ s the Password property, which can access the shared MinPasswordLength member: ‘Password property Public Property Password() As String Get Return strPassword End Get Set(ByVal value As String) If value.Length > = MinPasswordLength Then strPassword = value End If End Set End Property What ’ s important to realize here is that although the Password property and strPassword member belong to the particular instance of the User class, MinPasswordLength does not; therefore, if it is changed the effect is felt throughout all the object instances built from the class in question. c12.indd 431c12.indd 431 4/1/08 6:36:20 PM4/1/08 6:36:20 PM Chapter 12: Advanced Object - Oriented Techniques 432 In the form, UpdateDisplay is used to populate the list. You can gain access to MinPasswordLength as if it were a normal, nonshared public member of the User object: Private Sub UpdateDisplay() ‘Clear the list lstUsers.Items.Clear() ‘Add the users to the list box For Each objUser As User In arrUserList lstUsers.Items.Add(objUser.Username & “, “ & objUser.Password & _ “ (“ & User.MinPasswordLength & “)”) Next End Sub At this point, you have a listing of users that shows that the MinPasswordLength value of each is set to 6 (refer to Figure 12 - 10 ). Things start to get interesting when you scroll the NumericUpDown control and change MinPasswordLength . As this is a shared member, you don ’ t specifically need an instance of the class. Instead, you can set the property just by using the class name: Private Sub nudMinPasswordLength_ValueChanged(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles nudMinPasswordLength.ValueChanged ‘Set the minimum password length User.MinPasswordLength = nudMinPasswordLength.Value ‘Update the display UpdateDisplay() End Sub When building this method, you may notice that after you type User ., Visual Studio 2008 ’ s IntelliSense pops up a list of members, including the MinPasswordLength property, as shown in Figure 12 - 11 . Figure 12 - 11 Shared members, properties, and methods can all be accessed through the class directly — you don ’ t specifically need an instance of the class. When you change this member with code in the ValueChanged event handler, you update the display, and this time you can see that the perceived value of MinPasswordLength has seemingly been changed for all instances of User , even though you changed it in only one place. c12.indd 432c12.indd 432 4/1/08 6:36:20 PM4/1/08 6:36:20 PM Chapter 12: Advanced Object - Oriented Techniques 433 Using Shared Methods Although you ’ ve seen how to make a public member variable shared, you haven ’ t seen how to do this with a method. In the following Try It Out, you look at an example of how to build a shared method that can create new instances of User . The main limitation with a shared method is that you can access other shared methods and shared properties only in the class in which it is defined. This is a hypothetical example of using a shared method, as you could do the same job here with a customized constructor. Try It Out Using a Shared Method 1. Open the Code Editor for User . Add the following code to the User class: Public Shared Function CreateUser(ByVal userName As String, _ ByVal password As String) As User ‘Delcare a new User object Dim objUser As New User() ‘Set the User properties objUser.Username = userName objUser.Password = password ‘Return the new user Return objUser End Function 2. Open the Code Editor for Form1 and locate the Load event handler. Change the code so that it looks like this. You ’ ll notice that as you type in the code, as soon as you type User ., IntelliSense offers CreateUser as an option: Private Sub Form1_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load ‘Load 100 users For intIndex As Integer = 1 To 100 ‘Create a new user Dim objUser As New User objUser = User.CreateUser(“Stephanie” & intIndex, “password15”) ‘Add the user to the array list arrUserList.Add(objUser) Next ‘Update the display UpdateDisplay() End Sub 3. If you run the project, you get the same results as the previous example. c12.indd 433c12.indd 433 4/1/08 6:36:20 PM4/1/08 6:36:20 PM Chapter 12: Advanced Object - Oriented Techniques 434 How It Works The important thing to look at here is the fact that CreateUser appears in the IntelliSense list after you type the class name. This is because it is shared and you do not need a specific instance of a class to access it. You create the method as a shared method by using the Shared keyword: Public Shared Function CreateUser(ByVal userName As String, _ ByVal password As String) As User One thing to consider with shared methods is that you can access only members of the class that are also shared. You cannot access nonshared methods, simply because you don ’ t know what instance of the class you ’ re actually running on. Likewise, you cannot access Me from within a shared method for the same reason. Understanding Object - Oriented Programming and Memory Management Object orientation has an impact on how memory is used in an operating system. .NET is heavily object oriented, so it makes sense that .NET would have to optimize the way it uses memory to best suit the way objects are used. Whenever you create an object, you ’ re using memory. Most of the objects you use have state , which describes what an object knows. The methods and properties that an object has will either affect or work with that state. For example, an object that describes a file on disk will have state that describes its name, size, folder, and so on. Some of the state will be publicly accessible through properties. For example, a property called Size returns the size of the file. Some state is private to the object and is used to keep track of what the object has done or what it needs to do. Objects use memory in two ways. First, something needs to keep track of the objects that exist on the system in memory. This is usually a task shared between you as an application developer and .NET ’ s Common Language Runtime (CLR). If you create an object, you ’ ll have to hold a reference to it in your program ’ s memory so that you know where it is when you need to use its methods and properties. The CLR also needs to keep track of the object to determine when you no longer need it. Secondly, the CLR needs to allocate memory to the object so that the object can store its state. The more state an object has, the more memory it will need to use it. The most expensive resource on a computer is the memory. Expense here means in terms of what you get for your money. For about $100, you can buy a 120 GB hard drive, but for the same amount of money you can ’ t buy 1 GB of memory. Retrieving data from memory is thousands of times faster than retrieving it from disk so there ’ s a tradeoff — if you need fast access, you have to store it in memory, but there isn ’ t as much memory available as there is hard disk space. When building an application, you want to use as little memory as possible, so there ’ s an implication that you want to have as few objects as possible and that those objects should have as little state as possible. The upside is that, today, computers have a lot more memory than they used to have, so your c12.indd 434c12.indd 434 4/1/08 6:36:20 PM4/1/08 6:36:20 PM Chapter 12: Advanced Object - Oriented Techniques 435 programs can use more memory than their predecessors of 10 years ago. However, you still need to be cognizant of your application ’ s memory usage. The CLR manages memory in several distinct ways. First, it ’ s responsible for creating objects at the request of the application. With a heavily object - oriented programming platform like .NET, this is going to happen all the time, so Microsoft has spent an enormous amount of time making sure that the CLR creates objects in the most efficient way. The CLR, for example, can create objects far faster than its Component Object Model (COM) predecessor could. Secondly, the CLR is responsible for cleaning up memory when it ’ s no longer needed. In the developer community, the manner in which the CLR cleans up objects is one of the most controversial. Imagine you ’ re writing a routine that opens a file from disk and displays the contents on the screen. Well, with .NET you could use perhaps two .NET Framework objects to open the file and read its contents — namely System.IO.FileStream and System.IO.StreamReader . However, after the contents have been read, do you need these objects anymore? Probably not, so you remove your references to the objects and make the memory the objects were using available for creating more objects. Imagine now that you don ’ t remove your references to the objects. In this situation, the memory that the objects were using can ’ t be used by anyone else. Now imagine that happening several thousand times. The amount of memory that ’ s being wasted keeps growing. In extreme circumstances, the computer runs out of memory, meaning that other applications wouldn ’ t ever be able to create any objects. This is a pretty catastrophic state of affairs. We describe an object that is no longer needed but that holds onto memory as a leak . Memory leaks are one of the biggest causes of reliability problems on Windows, because when a program is no longer able to obtain memory, it will crash. With .NET this should never happen, or, at the very least, to leak memory you would have to go to some pretty extreme steps. This is because of a feature called garbage collection . When an object is no longer being used, the Garbage Collector automatically removes the object from memory and makes the memory it was using available to other programs. Garbage Collection The Garbage Collector (GC) works by keeping track of how many parts of a program have a reference to an object. If it gets to the point where there are no open references to the object, it is deleted. To understand this, think back to the discussion of scope in Chapter 3 . Imagine you create a method and at the top of that method you define a variable with local scope. That variable is used to store an object (it doesn ’ t matter what kind of object is used for this discussion). At this point, one part of the program knows about the object ’ s existence — that is, the variable is holding a reference to the object. When you return from the method, the variable goes out of scope, and therefore the variable forgets about the object ’ s existence; in other words, the only reference to the object is lost. At this point, no one knows about the object, and so it can be safely deleted. For an example, look at the following code: Dim objObject As New MyObject Console.WriteLine(objObject.GetType().FullName) objObject = Nothing c12.indd 435c12.indd 435 4/1/08 6:36:21 PM4/1/08 6:36:21 PM Chapter 12: Advanced Object - Oriented Techniques 436 This code snippet creates a new object from class MyObject , invokes a method on it, and then removes the reference to the object. In this case, when you create the object, the objObject variable is the only thing that holds a reference to it. In the last line, objObject is set to Nothing , hence removing the only reference to the object. The GC is then free to remove the reference to the object. The GC does not run constantly. Instead, it runs periodically based on a complex algorithm that measures the amount of work the computer is doing and how many objects might need to be deleted. When the GC runs, it looks through the master list of all the objects the program has ever created for any that can be deleted at this point. In old - school programming, programmers were responsible for deleting their own objects and had the freedom to say to an object, “ You, now, clean yourself up and get out of memory. ” With .NET this ability is gone. Rather, an object will be deleted at some indeterminate time in the future. Exactly when this happens is nondeterministic — in other words, as a developer you don ’ t know when the GC is going to run. This means that there is no immediate connection between the removal of the last reference to an object and the physical removal of that object from memory. This is known as nondeterministic finalization . Releasing Resources In some cases, objects that you build may need access to certain system and network resources, such as files and database connections. Using these resources requires a certain discipline to ensure that you don ’ t inadvertently cause problems. Here ’ s an example — if you create a new file, write some data to it, but forget to close it, no one else will be able to read data from that file. This is because you have an exclusive lock on the file; it doesn ’ t make sense for someone to be able to read from a file when it ’ s still being written to. You must take care to release system resources should you open them. When an object has access to scarce system or network resources like this, it ’ s important that the caller tell the object that it can release those resources as soon as they ’ re no longer needed. For example, here ’ s some code that creates a file: ‘Open a file Dim objFileStream As New FileStream(“c:\myfile.txt”, FileMode.Create) ‘Do something with the file ‘Close the file objFileStream.Close() ‘Release your reference to the object objFileStream = Nothing As soon as you finish working with the file, you call Close . This tells .NET that the consumer is finished with the file and Windows can make it available for other applications to use. This is known as releasing the lock . When you release the object reference in the next line by setting objFileStream = Nothing , this is an entirely separate action from calling Close . The FileStream object releases the lock on the file when its Finalize method is called. However, as you ’ ve just learned, the time period between the instance of the FileStream object becoming a c12.indd 436c12.indd 436 4/1/08 6:36:21 PM4/1/08 6:36:21 PM [...]... create a Windows Forms application, Visual Studio 2008 knows that you will be compiling it into a program that can run When you choose a Class Library, Visual Studio 2008 knows that the resulting library will not be run on its own — so the choices you make here affect what Visual Studio 2008 does when you build the project Selecting a Class Library means that Visual Studio 2008 will build the project into... you create a new key pair From the Windows Start menu select All Programs Visual Studio 2008 Visual Studio Tools Microsoft Visual Studio 2008 Command Prompt If you are running on Windows Vista, you will most likely need to run the command prompt with administrator privileges To do this, instead of left-clicking the Visual Studio 2008 Command Prompt, right-click it and choose Run as administrator from... and revision number will be generated by Visual Studio 2008 Every time you recompile the assembly, Visual Basic 2008 will adjust these numbers to ensure that every compilation has a unique version number You could choose to replace the build and revision numbers with your own hard-coded numbers and increment them yourself, but if you’re happy with Visual Basic 2008 s decision, then you can just leave... factor is an important reason why Visual Basic, in general, became one of the most popular and is one of the most powerful development languages in use today Did you know that you owe much of what you experience today in Visual Studio 2008, like Windows Forms Controls, to Visual Basic? The history of Windows Forms Controls has roots in something known as controls Visual Basic Extension (VBX) This later... Windows XP and Windows Vista) 449 c13.indd 449 4/1/08 6: 37:43 PM Chapter 13: Building Class Libraries Gacutil Utility Gacutil.exe is a utility provided with the NET Framework for installing/uninstalling assemblies into the GAC via a command line From the Windows Start menu, select Programs Microsoft Visual Studio 2008 Visual Studio Tools Visual Studio 2008 Command Prompt Navigate to the bin folder for... the expression “DLL Hell.” However, Visual Basic 2008 goes a long way toward solving the problem The problem is connected with two things: ❑ There can be several versions of a DLL, and these can all work in different ways It is not possible to tell the version from the file name alone ❑ Different people can write DLLs with the same file name 4 46 c13.indd 4 46 4/1/08 6: 37:42 PM Chapter 13: Building Class... to the Class Library project Try It Out Adding a Class Library Project to an Existing Solution 1 Switch to the instance of Visual Studio 2008 containing the Internet Favorites project 2 Save the project and then close Visual Studio 2008 3 Switch to the instance of Visual Studio 2008 containing the Favorites Viewer project 4 Click the File menu and select Add 5 Existing Project Navigate to the where... used within Visual Basic 2008, you can use a quick and easy tool known as the Object Browser You can also use the Object Browser to view class names and method names on objects The Object Browser window can be viewed inside Visual Studio 2008 by pressing F2 It is also available by clicking the View Object Browser menu or by clicking the Object Browser icon on the toolbar The Object Browser is basically... c13.indd 454 4/1/08 6: 37:44 PM Chapter 13: Building Class Libraries Remember that an assembly can contain several namespaces and that the same namespace can be spread across several assemblies It just happens that in Visual Basic 2008 you normally have a single namespace inside a single assembly of the same name The MSDN Library documentation that gets installed with Visual Studio 2008 contains plenty... pair in the folder where the command is run (in this case, C:\Program Files \Microsoft Visual Studio 9.0\VC) How It Works Running the Visual Studio 2008 command prompt opens a DOS-style command window with the environment set up so that you can use the NET command-line tools You use this environment to run the Visual Studio 2008 strong naming command, sn The k switch means that the command generates . period between the instance of the FileStream object becoming a c12.indd 436c12.indd 4 36 4/1/08 6: 36: 21 PM4/1/08 6: 36: 21 PM Chapter 12: Advanced Object - Oriented Techniques 437 candidate for. the instance of Visual Studio 2008 containing the Internet Favorites project. 2. Save the project and then close Visual Studio 2008. 3. Switch to the instance of Visual Studio 2008 containing. Property End Class c12.indd 429c12.indd 429 4/1/08 6: 36: 19 PM4/1/08 6: 36: 19 PM Chapter 12: Advanced Object - Oriented Techniques 430 6. View the code for Form1 and add this highlighted member: