Chapter 17. Using Enumerations and Structures

The data types you've learned about so far hold strings, integers, dates, and other predefined kinds of information, but sometimes it would be nice to define your own data types. You might like to be able to make a data type that can hold only certain values, such as a MealType data type that can hold the values Breakfast, Lunch, and Dinner. You might also like to define a type to hold related pieces of data (such as name, address, and phone number) in a single variable.

Enumerations and structures enable you to do these things. An enumeration (or enumerated type) enables you to define a new data type that can take only one of an allowed list of values. A structure enables you to define a group of related pieces of data that should be kept together.

In this lesson, you learn how to define and use enumerations and structures to make your code easier to understand and debug.

ENUMERATIONS

An enumeration is simply a data type that allows only specific values. The following code defines a ContactMethod enumeration that can hold the values None, Email, Phone, or SnailMail:

' Define possible contact methods.
Private Enum ContactMethod As Integer
    None = 0
    Email
    Phone
    SnailMail
End Enum

Internally, an enumeration is stored as an integral data type, by default an Integer. A number after a value tells Visual Basic explicitly which integer to assign to that value. In the preceding code, None is explicitly assigned the value 0.

If you don't specify a value for an enumeration's item (and often you don't care what these values are), its value is one greater than the previous item's value (the first item gets the value 0). In this example, None is 0, Email is 1, Phone is 2, and SnailMail is 3.

You create an instance of an enumerated type just as you make an instance of a primitive type such as Integer, Decimal, or String. The following code declares a variable of type ContactMethod, assigns it the value ContactMethod.Email, and then displays its value in a message box:

Dim method As ContactMethod = ContactMethod.Email
MessageBox.Show(method.ToString())

An enumeration's ToString method returns the value's name, in this case "Email."

STRUCTURES

Defining a structure is easy. The following code defines a simple structure named Address that holds name and address information:

' Define a structure to hold addresses.
Private Structure Address
    Public Name As String
    Public Street As String
    Public City As String
    Public State As String
    Public Zip As String
    Public Email As String
    Public Phone As String
    Public PreferredMethod As ContactMethod
End Structure

The structure begins with a Structure statement that defines the structure's name and ends with an End Structure statement. The lines in between define the pieces of data that the structure holds together. The Public keywords in this example mean that the fields inside the structure (Name, Street, and so on) are visible to any code that can see an Address.

Notice that the structure can use an enumeration. In this example, the Address structure's PreferredMethod field has type ContactMethod.

In many ways structures behave like simple built-in types such as Integer and Single. In particular, when you declare a variable with a structure type, the code not only declares it but also creates it. That means you don't need to use the New keyword to create a structure.

After defining a structure variable, you can access its fields using syntax similar to the way you access a control's properties. Start with the variable's name, follow it with a dot, and then add the field's name.

The following code creates and initializes a new Address structure named homeAddress:

Dim homeAddress As Address
homeAddress.Name = txtName.Text
homeAddress.Street = txtStreet.Text
homeAddress.City = txtCity.Text
homeAddress.State = txtState.Text
homeAddress.Zip = txtZip.Text
homeAddress.Email = txtEmail.Text
homeAddress.Phone = txtPhone.Text
homeAddress.PreferredMethod =
    CType(cboMethod.SelectedIndex, ContactMethod)

This code fills in the text fields using values entered by the user in textboxes.

The final field is a ContactMethod enumeration. The user selects a value for this field from the cboMethod ComboBox. The code takes the index of the ComboBox's selected item, uses CType to convert it from an integer into a ContactMethod, and saves the result in the structure's PreferredMethod field.

Note

To correctly convert a ComboBox selection into an enumeration value, the ComboBox must display the choices in the same order in which they are defined by the enumeration. In this example, the ComboBox must contain the items None, Email, Phone, and SnailMail, in that order, to match up with the enumeration's items.

STRUCTURES VERSUS CLASSES

In many ways structures are very similar to classes. Lessons 23 through 30 say a lot more about classes and the sorts of things you can do with them, and many of the same techniques apply to structures.

For example, both can contain properties, methods, and events. Both can also have constructors, special methods that are executed when you use New to create a new one.

While structures and classes have many things in common, they also have many differences. A lot of these differences are outside the scope of this book, so I won't cover them here, but one very important difference that you should understand is that structures are value types, whereas classes are reference types.

  • A reference type variable doesn't actually hold an instance of a class. Instead it holds a reference to an instance. For example, the following code creates a reference to an object of type NewUserForm. The second statement actually creates that instance and then the third statement displays it. If you tried to display the form without the second statement, the program would crash because the variable wouldn't be referring to an instance yet.

    Dim userForm As NewUserForm
    userForm = New NewUserForm()
    userForm.ShowDialog()
  • In contrast, a value type variable actually contains its data instead of referring to it. For example, the following code declares an Address variable. After the first statement, the variable already contains an Address structure, its fields have default values, and it is ready for use.

    Dim homeAddress As Address
    homeAddress.Name = "Benjamin"

One other important difference between value and reference types is that when you set a variable with a value type equal to another, the first variable receives a copy of the second variable's value. For example, if x and y are integers, then the statement x = y makes x hold the same value as y.

Similarly, if ann and ben are variables of the structure type Person, then ben = ann makes all of the fields in ben have the same values as all of the fields in ann, but they are still two separate Person structures.

In contrast, if you set a reference type variable equal to another, the first variable now refers to the same object as the other, not just a copy of that object. For example, suppose cindy and dan are two variables that hold references to Student objects. The statement dan = cindy makes the variable dan refer to the same object to which cindy refers. If you change one of dan's properties, cindy also sees the change because they point to the same object.

The StructureVersusClass example program that is available in the Lesson 17 download demonstrates this difference.

So which should you use, a structure or a class? In many programs the difference doesn't matter much. As long as you are aware of the relevant differences, you can often use either.

Microsoft's "Classes and Structs (C# Programming Guide)" web page at msdn.microsoft.com/library/ms173109.aspx gives the following advice (though that page is discussing C# programming, its advice also applies to Visual Basic):

In general, classes are used to model more complex behavior, or data that is intended to be modified after a class object is created. Structs are best suited for small data structures that contain primarily data that is not intended to be modified after the struct is created.

TRY IT

In this Try It, you use an enumeration and a structure to make the address book shown in Figure 17-1. When the user clicks the Add button, the program saves the entered address values. If the user enters a name and clicks Find, the program retrieves the corresponding address data.

FIGURE 17-1

Figure 17.1. FIGURE 17-1

Note

You can download the code and resources for this Try It from the book's web page at www.wrox.com or www.vb-helper.com/24hourvb.html. You can find them in the Lesson17 folder in the download.

Lesson Requirements

In this lesson:

  • Create the form shown in Figure 17-1.

  • Define the ContactMethod enumeration with values None, Email, Phone, and SnailMail.

  • Define an Address structure to hold the entered address information.

  • Create a Dictionary(Of String, Address) field to hold the address data.

  • Add code to initially select the ComboBox's None entry when the form loads (just so something is selected).

  • Add code to the Add button that creates the new entry in the Dictionary.

  • Add code to the Find button that retrieves the appropriate entry from the Dictionary and displays it.

Hints

  • Remember to add the choices to the ComboBox in the same order they are defined in the ContactMethod enumeration.

  • Use CType to convert from a ComboBox's selected index to a ContactMethod.

  • Use CInt to convert from a ContactMethod to a ComboBox's selected index.

Step-by-Step

  • Create the form shown in Figure 17-1.

    1. This is relatively straightforward.

  • Define the ContactMethod enumeration with values None, Email, Phone, and SnailMail.

    1. Use code similar to the following:

      ' Define possible contact methods.
      Private Enum ContactMethod
          None = 0
          Email
          Phone
          SnailMail
      End Enum
  • Define an Address structure to hold the entered address information.

    1. Use code similar to the following:

      ' Define a structure to hold addresses.
      Private Structure Address
          Public Name As String
          Public Street As String
          Public City As String
          Public State As String
          Public Zip As String
          Public Email As String
          Public Phone As String
          Public PreferredMethod As ContactMethod
      End Structure
  • Create a Dictionary(Of String, Address) field to hold the address data.

    1. Use code similar to the following:

      ' Make a Dictionary to hold addresses.
      Private Addresses As New Dictionary(Of String, Address)()
  • Add code to initially select the ComboBox's None entry when the form loads.

    1. Use code similar to the following:

      cboMethod.SelectedIndex = 0
  • Add code to the Add button that creates the new entry in the Dictionary.

    1. Use code similar to the following. Optionally, you can clear the TextBoxes to get ready for the next address.

      ' Add a new address.
      Private Sub btnAdd_Click() Handles btnAdd.Click
          Dim newAddress As Address
          newAddress.Name = txtName.Text
          newAddress.Street = txtStreet.Text
          newAddress.City = txtCity.Text
          newAddress.State = txtState.Text
          newAddress.Zip = txtZip.Text
          newAddress.Email = txtEmail.Text
          newAddress.Phone = txtPhone.Text
          newAddress.PreferredMethod =
              CType(cboMethod.SelectedIndex, ContactMethod)
      
          ' Add the name and address to the dictionary.
          Addresses.Add(txtname.Text, newAddress)
      
          ' Get ready for the next one.
          txtName.Clear()
          txtStreet.Clear()
          txtCity.Clear()
          txtState.Clear()
          txtZip.Clear()
      txtEmail.Clear()
          txtPhone.Clear()
          cboMethod.SelectedIndex = 0
      
          txtname.Focus()
      End Sub
  • Add code to the Find button that retrieves the appropriate entry from the Dictionary and displays it.

    1. Use code similar to the following:

      ' Look up an address.
      Private Sub btnFind_Click() Handles btnFind.Click
          ' Get the Address.
          Dim selectedAddress As Address = Addresses(txtName.Text)
      
          ' Display the Address's values.
          txtname.Text = selectedAddress.Name
          txtStreet.Text = selectedAddress.Street
          txtCity.Text = selectedAddress.City
          txtState.Text = selectedAddress.State
          txtZip.Text = selectedAddress.Zip
          txtEmail.Text = selectedAddress.Email
          txtPhone.Text = selectedAddress.Phone
          cboMethod.SelectedIndex =
              CInt(selectedAddress.PreferredMethod)
      End Sub

Note

Please select Lesson 17 on the DVD to view the video that accompanies this lesson.

EXERCISES

  1. Copy the program you built for this lesson's Try It. Add a Remove button that removes an item by calling the Dictionary's Remove method.

  2. Copy the program you built for Exercise 1. Modify it by adding a new integer Id field to the structure. Then create a second Dictionary that uses Id as its key. Allow the user to click the Find by Name or Find by ID buttons to locate an item using either the customer's name or ID. Also provide Remove buttons that remove by name or ID. (Hint: When the user clicks a Remove button, be sure to remove the item from both Dictionaries.)

  3. Make a program to store appointment data similar to the program you built for Exercise 1. Use a structure with the following fields: Time, Attendees, Type, Topic, and Notes. Make Type come from the AppointmentType enumeration that includes the values None, Work, Home, and Other. (Hint: See Lesson 16's Exercise 4 for tips on how to use a DateTimePicker control's values as keys.)

Note

You can find solutions to this lesson's exercises in the Lesson17 folder inside the download available on the book's web site at www.wrox.com or www.vb-helper.com/24hourvb.html.

EXERCISES
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset