Defining Shared Properties
As a general rule, fields are declared as private members. You can declare shared fields as private members too and use shared properties to provide access to shared fields.
A property is a special kind of method that is used like data but calls getter and setter methods, which for all intents and purposes are methods. The relationship is that fields are private and properties provide a public means of accessing data through implicit calls to property methods with the ease of using data. Thus you would use shared fields and properties in pairs just as you would use instance fields and properties in pairs. To define shared properties, you will need to place the Shared keyword between the access specifier and the keyword property.
If you are going to implement validation procedures for shared properties, the validation procedures need to be shared too. Any shared fields, properties, and methods that interact must interact with shared methods. Listing 11.1 defines a structure and class with examples of shared fields and shared properties.
Listing 11.1 Shared fields and properties defined in a class and structure
1: Public Class PropertyExamples 2: Private Shared FInt As Integer 3: 4: Public Shared Property Int() As Integer 5: Get 6: Return FInt 7: End Get 8: Set(ByVal Value As Integer) 9: FInt = Value 10: End Set 11: End Property 12: 13: Public Shared ReadOnly Property Name() As String 14: Get 15: Return "SharedStructureProperties" 16: End Get 17: End Property 18: 19: Private Shared FReference As Date 20: Public Shared WriteOnly Property Reference() As Date 21: Set(ByVal Value As Date) 22: FReference = Value 23: End Set 24: End Property 25: 26: End Class 27: 28: Public Structure SharedStructureProperties 29: Public Dummy As Integer 30: 31: Private Shared FInt As Integer 32: 33: Public Shared Property Int() As Integer 34: Get 35: Return FInt 36: End Get 37: Set(ByVal Value As Integer) 38: FInt = Value 39: End Set 40: End Property 41: 42: Public Shared ReadOnly Property Name() As String 43: Get 44: Return "SharedStructureProperties" 45: End Get 46: End Property 47: 48: Private Shared FReference As Date 49: Public Shared WriteOnly Property Reference() As Date 50: Set(ByVal Value As Date) 51: FReference = Value 52: End Set 53: End Property 54: 55: End Structure
Listing 11.1 defines shared fields and properties for syntactical demonstration rather than utility. Most importantly, notice that the shared elements in both the class and structure use an identical syntax (and, in fact, are identical). The class defines a private field FInt on line 2 represented by the shared property Int on lines 4 through 11. Note the exact same implementation in the structure on lines 31 through 40. Lines 13 through 17 define a shared ReadOnly property Name that returns a literal string containing the name of the structure. Properties with the ReadOnly modifier can only be used as a right-hand side value in statements. Lines 19 through 24 implement a WriteOnly shared property Reference, which is defined as a Date and is written to the FReference field.
Listing 11.1 duplicates the members of the class in the structure to demonstrate that identical syntax for shared fields and properties. The only difference between the structure and class is that the structure must have at least one nonshared member.
Structures require at least one nonshared member, hence the Public Dummy As Integer member on line 29 of Listing 11.1 in the structure SharedStructureProperties.
Other than the Shared keywords, shared property and field declarations are identical to nonshared members. Listing 11.2 demonstrates the aggregate types defined in Listing 11.1.
Listing 11.2 Using shared properties of structures and fields
1: PropertyExamples.Int = 10 2: Debug.WriteLine(PropertyExamples.Int) 3: Debug.WriteLine(PropertyExamples.Name) 4: PropertyExamples.Reference = Now 5: 6: SharedStructureProperties.Int = 13 7: Dim Struct As SharedStructureProperties 8: Debug.WriteLine(Struct.Int) 9: Struct.Int = -1 10: Debug.WriteLine(SharedStructureProperties.Int) 11: 12: Debug.WriteLine(SharedStructureProperties.Name) 13: SharedStructureProperties.Reference = Now 14: 15: Debug.WriteLine(Struct.Name = SharedStructureProperties.Name)
Line 1 of Listing 11.2 uses the Shared Int property of the PropertyExamples class. Line 3 demonstrates using the ReadOnly Name property of the same class, and line 4 assigns the current date and time to the PropertyExamples.Reference property. It's important to note that all references to properties on lines 1 through 4 are successfully accomplished using the class in the form class.property .
Line 6 assigns the value 13 to the shared property of the structure named SharedStructureProperties. Line 7 declares a structure instance and line 8 writes the value of the Int property using the instance Struct. If you guessed that 13 is written to the Output window, you're getting the hang of shared fields and properties. Line 9 assigns -1 to the Int property. The result of the assignment on line 9 is that every instance of SharedStructureProperties will have the value -1 assigned to the field FInt, including instances not yet in existence. The remaining lines demonstrate that values assigned to the properties through the instance are reflected in the property accessed by the structure. The output from Listing 11.2 is listed next (without the symbol loading information):
10 SharedStructureProperties 13 -1 SharedStructureProperties True
You can save the contents of the Output window to a file by selecting the Output window and clicking File, Save in the development environment.
Shared fields and properties aren't used heavily; on occasion you might encounter them or contrive a use that makes sense to you. If you encounter them in code, you will know what they are and have some ideas as to how the author of the code might be using the shared fields and properties. Listing 11.3 implements a class with all shared members that describe a self-contained counter. I commonly need a unique number or test data when developing applications; the following examples preclude the need to declare a local integer and write the code to increment the counter.
Listing 11.3 A self-contained counter using shared members
1: Public Class Counter2 2: Private Shared FValue As Long 3: 4: Public Shared Sub Reset() 5: FValue = -1 6: End Sub 7: 8: Public Shared ReadOnly Property Value() As Long 9: Get 10: FValue += 1 11: Return FValue 12: End Get 13: End Property 14: 15: End Class
The shared field FValue stores the count. The shared method Reset initializes the field value to -1 and the shared property Value increments the field and returns the field value. The field value is initialized to -1, and the increment is performed first because the Return statement in Visual Basic .NET actually causes the code to branch out of the block on the line of code containing the Return statement (see line 11). To use the code in Listing 11.3, simply call Counter2.Reset() to initialize the counter and write Counter2.Value to increment and return the current counter value.
Shared methods are more commonly employed than shared fields and properties. But, if the value of a shared method needs to be stored, you will encounter shared fields and properties along with shared methods. Let's take a look at shared methods next.