The syntax for declaring a structure is almost identical to that for a class:
[attributes] [access-modifiers] Structure identifier [Implements4 interface-list] structure-members End Structure
Attributes are discussed in Chapter 18. Access modifiers (Public, Private, etc.) work just as they do with classes. (See Chapter 5 for a discussion of access modifiers.) The keyword Structure is followed by an identifier (the name of the structure). The optional interface-list is explained in Chapter 8. Within the body of the structure, you define fields and methods, also called the structure members, just as you do in a class.
Example 7-1 defines a structure named Location to hold x,y coordinates of an object displayed on the screen.
Option Strict On
Imports System
Namespace StructureDemonstration
' declare a Structure named Location
Public Structure Location
' the structure has private data
Private myXVal As Integer
Private myYVal As Integer
' constructor
Public Sub New( _
ByVal xCoordinate As Integer, ByVal yCoordinate As Integer)
myXVal = xCoordinate
myYVal = yCoordinate
End Sub 'New
' property
Public Property XVal( ) As Integer
Get
Return myXVal
End Get
Set(ByVal Value As Integer)
myXVal = Value
End Set
End Property
Public Property YVal( ) As Integer
Get
Return myYVal
End Get
Set(ByVal Value As Integer)
myYVal = Value
End Set
End Property
' Display the structure as a String
Public Overrides Function ToString( ) As String
Return String.Format("{0}, {1}", xVal, yVal)
End Function 'ToString
End Structure 'Location
Class Tester
Public Sub Run( )
' create an instance of the structure
Dim loc1 As New Location(200, 300)
' display the values in the structure
Console.WriteLine("Loc1 location: {0}", loc1)
' invoke the default constructor
Dim loc2 As New Location( )
Console.WriteLine("Loc2 location: {0}", loc2)
' pass the structure to a method
myFunc(loc1)
' redisplay the values in the structure
Console.WriteLine("Loc1 location: {0}", loc1)
End Sub 'Run
' method takes a structure as a parameter
Public Sub myFunc(ByVal loc As Location)
' modify the values through the properties
loc.XVal = 50
loc.YVal = 100
Console.WriteLine("Loc1 location: {0}", loc)
End Sub 'myFunc
Shared Sub Main( )
Dim t As New Tester( )
t.Run( )
End Sub 'Main
End Class 'Tester
End Namespace 'StructureDemonstration
Output:
Loc1 location: 200, 300
Loc2 location: 0, 0
Loc1 location: 50, 100
Loc1 location: 200, 300
The Location structure is defined as public, much as you might define a class.
Public Structure Location
' the structure has private data
Private myXVal As Integer
Private myYVal As Integer
As with a class, you can define a constructor and properties for the structure. For example, you might create integer member variables myXVal and myYVal, and then provide public properties for them named XVal and YVal (see Chapter 5):
' constructor
Public Sub New( _
ByVal xCoordinate As Integer, ByVal yCoordinate As Integer)
myXVal = xCoordinate
myYVal = yCoordinate
End Sub 'New
Public Property XVal( ) As Integer
Get
Return myXVal
End Get
Set(ByVal Value As Integer)
myXVal = Value
End Set
End Property
Public Property YVal( ) As Integer
Get
Return myYVal
End Get
Set(ByVal Value As Integer)
myYVal = Value
End Set
End Property
There is no difference in the way you create constructors and properties in structures and the way you do so in classes. However, you are not permitted to create a custom default constructor for a structure. That is, you cannot write a constructor with no parameters. Thus the following code would not compile:
' won't compile - no custom default ' constructors for structures Public Sub New( ) xVal = 5 yVal = 10 End Sub 'New
Instead, the compiler creates a default constructor for you (whether or not you create other constructors), and that default constructor initializes all the member values to their default values (e.g., integers are initialized to zero).
The Run( ) method of the Tester class creates an instance of the Location structure named loc1, passing in the initial x,y coordinates of 200,300:
Dim loc1 As New Location(200, 300)
Loc1 is then passed to WriteLine( ) to display the x,y values:
Console.WriteLine("Loc1 location: {0}", loc1)
When you pass the loc1 object to Console.WriteLine( ), WriteLine( ) automatically invokes the overridable ToString( ) method on the object. Thus, Location.ToString( ) is invoked, which displays the x and y coordinates of the loc1 object:
Loc1 location: 200, 300
Before modifying the values in loc1, the example creates a second instance of the Location structure, named loc2, and displays its values:
Dim loc2 As New Location( )
Console.WriteLine("Loc2 location: {0}", loc2)
The creation of loc2 invokes the default constructor (note that no parameters are passed in). The output shows that the compiler-provided default constructor initialized the member variables to default values.
Loc2 location: 0, 0
You next pass your first structure, loc1, whose values are 200,300, to a method, myFunc( ). In that method, the parameter is a Location object named loc. Within the myFunc( ) method, the XVal property is used to set the x coordinate to 50, and the YVal property is used to set the y coordinate to 100; then the new value is displayed using WriteLine( ):
Public Sub myFunc(ByVal loc As Location)
' modify the values through the properties
loc.XVal = 50
loc.YVal = 100
Console.WriteLine("Loc1 location: {0}", loc)
End Sub 'myFunc
As expected, the results show the modification:
Loc1 location: 50, 100
When you return to the calling method (Run( )), the values of loc1 are displayed, showing they are unchanged from before the call to myFunc( ):
Loc1 location: 200, 300
When you passed loc1 to myFunc( ), the structure was passed by value (structures, like the intrinsic types, are value types). A copy was made, and it was on that copy that you changed the values to 50 and 100. The original Location structure (loc1) was unaffected by the changes made within myFunc( ).
Unlike classes, structures do not support inheritance. Structures implicitly derive from Object (as do all types in VB.NET, including the built-in types) but cannot inherit from any other class or structure. Structures are also implicitly not-inheritable (that is, no class or structure can derive from a structure). See Chapter 6 for a discussion of inheritance and not-inheritable classes.
You cannot initialize an instance field in a structure. Thus, it is illegal to write:
Private xVal As Integer = 50 Private yVal As Integer = 100
though this kind of initialization is perfectly legal in a class. You must instead set the value of your member fields in the body of the constructor. As noted earlier, the default constructor (provided by the compiler) will set all the member variables to their default value.
Structures are designed to be simple and lightweight. While private member data promotes data hiding and encapsulation, some programmers feel it is overkill for structures. They make the member data public, thus simplifying the implementation of the structure. Other programmers feel that properties provide a clean and simple interface, and that good programming practice demands data hiding even with simple lightweight objects. Which you choose is a matter of design philosophy; the language will support either approach.
|
|
| Top |