Saturday, December 26, 2009

Attributes

You can’t entirely define a class in the code window. In fact, you must specify a few important attributes in a different way. These attributes might concern the class module as a whole or its individual members (that is, its properties and methods).
Class module attributes
The attributes of the class module itself are conceptually simpler because you can edit them through the Properties window, as you might for any other source code module that can be hosted in the Visual Basic environment. But in contrast to what happens with form and standard modules, what you see in the Properties window when you press the F4 key depends on the type of the project. (See Figure.) There are six attributes: Name, DataBindingBehavior, DataSourceBehavior, Instancing, MTSTransactionMode, and Persistable. They will be covered in detail in subsequent chapters.




Only a Public class module in an ActiveX DLL project exposes all possible class attributes in the Properties window.

The default member of a class
Most Visual Basic controls and intrinsic objects expose a default property or method. For example, the TextBox control’s default property is Text; the Error object’s default property is Number; Collections have a default Item method; and so on. Such items are said to be default members because if you omit the member name in an expression, Visual Basic will implicitly assume you meant to refer to that particular member. You can implement the same mechanism even with your own classes by following this procedure:
1. Click in the code editor on the property or method definition, invoke the Procedure Attributes command from the Tools menu, and then select the name of the item in the topmost combo box if it isn’t already displayed.
2. Alternatively, press F2 to open the Object Browser, select the class module name in the leftmost pane; in the rightmost pane, right-click the item that must become the default member, and then select the Properties command from the pop-up menu that appears, as you can see in Figure





Selecting the Properties menu command from the Object Browser.
3. Once the item you’re interested in is highlighted in the topmost Name combo box, click on the Advanced button to expand the Procedure Attributes dialog box. (See Figure on the following page.)




The expanded view of the Procedure Attributes dialog box.

4. In the Procedure ID combo box, select the (default) item; alternatively, you can just type 0 (zero) in the edit area of the combo box.
5. Click the OK button to make your decision permanent, and close the dialog box. In the Object Browser, you’ll notice that a small, round indicator has appeared next to the member’s name. This is the confirmation that it has become the default member of the class.
A class can’t expose more than one default property or method. If you try to create a second default item, Visual Basic complains and asks you to confirm your decision. In general, it isn’t a good idea to change the default member of a class because this amendment could break all the client code written previously.
While I certainly agree that providing a default property to a class module tends to make it more easily usable, I want to warn you against some potential problems that can arise from using this feature. Let’s go back to our CPerson class and its HomeAddress and WorkAddress properties. As you know, you can assign one object property to another, as in this code:
Set pers.HomeAddress = New CAddress
Set pers.WorkAddress = New CAddress
pers.HomeAddress.Street = "2233 Ocean St."
...
Set pers.WorkAddress = pers.HomeAddress ‘ This person works at home.
Since the preceding code uses the Set command, both properties are actually pointing to the same CAddress object. This is important because it implies that no additional memory has been allocated to store this duplicate data and also because you can then freely modify the address properties through any of the two CPerson properties without introducing any inconsistencies:
pers.HomeAddress.Street = "9876 American Ave"
Print pers.WorkAddress.Street ‘ Correctly displays "9876 American Ave"
Now see what happens if you mistakenly omit the Set keyword in the original assignment:
pers.WorkAddress = pers.HomeAddress ‘ Error 438 "Object doesn’t support
‘ this property or method"
Don’t be alarmed by this (admittedly cryptic) error message: You made a logic error in your code, and Visual Basic has spotted it for you at run time, which is a good thing. Alas, this helpful error disappears if the class exposes a default property. To see it for yourself, make Street the default item of the class, and then run this code:
Set pers.HomeAddress = New CAddress
Set pers.WorkAddress = New CAddress
pers.HomeAddress.Street = "2233 Ocean St."
pers.WorkAddress = pers.HomeAddress ‘ No error! But has it worked?
Instead of rejoicing about the absence of an error message, see how the two properties are now related to each other:
‘Change the Street property of one object.
pers.HomeAddress.Street = "9876 American Ave"
Print pers.WorkAddress.Street ‘ Still displays "2233 Ocean St."
In other words, the two properties aren’t pointing to the same object anymore. The assignment without the Set command has cheated the compiler into thinking that we were asking it to assign the values of the default Street property (which is a legal operation) and that we weren’t interested in creating a new reference to the same object.
In short, by adding a default property you have deprived yourself of an important cue about the correctness of your code. My personal experience is that missing Set commands are subtle bugs that are rather difficult to exterminate. Keep this in mind when you’re deciding to create default properties. And if you’re determined to create them, always double-check your Set keywords in code.
Caution You might notice that if the object property on the left side of the assignment is Nothing, Visual Basic correctly raises error 91 even if we omit the Set keyword. This doesn’t happen, however, if the target property had been declared to be auto-instancing because in that case Visual Basic would create an object for you. This is just further proof that auto-instancing objects should always be looked at with suspicion.

No comments:

Post a Comment