Export (0) Print
Expand All

Walkthrough: Creating Your Own Collection Class

Visual Studio .NET 2003

You can create your own collection classes by inheriting from one of the many .NET Framework collection classes and adding code to implement your own custom functionality. In this topic, you will use inheritance to create a simple, strongly typed collection inherited from CollectionBase.

The .NET Framework provides several collection-type classes in the System.Collections namespace. Some, such as Stack, Queue, and Dictionary, are specialized classes that have been implemented to fulfill specific roles. Others, such as CollectionBase and DictionaryBase, are MustInherit (abstract) classes that have some basic functionality in place, but which leave much of the implementation to the developer.

The CollectionBase class already has implementations for the Clear method and the Count property, and it maintains a Protected property called List, which it uses for the internal storage and organization. Other methods, such as Add and Remove, as well as the Item property, require implementation.

In this walkthrough, you use the CollectionBase class to create a class called WidgetCollection. This is a collection that accepts only widgets, and exposes its members as Widget types, instead of accepting objects and exposing members as Object type. You then implement methods to add widgets to your collection and to remove the widget at a specific index, and you also implement an Item property that returns the widget object at the appropriate index.

Creating the Classes

The first step is to create a Widget class to put into your WidgetCollection.

To create the Widget class

  1. Open a new Windows Application and name it WidgetProject. From the Project menu, choose Add Class. In the Add New Item dialog box, name your class Widget.vb for Visual Basic and Widget.cs for Visual C#.

    The Code Editor for the Widget class opens.

  2. Add a public Name variable to your Widget class. Your code should look similar to the following:
    ' Visual Basic
    Public Class Widget
       Public Name as String
    End Class
    
    // C#
    public class Widget
       {
          public string Name;
          public Widget()
          {
          }
       }
    
  3. From the File menu, choose Save All.

You have now created a Widget class for use with the WidgetCollection class you create next. The Widget class is a simple class, which serves to illustrate how your strongly typed collection will work. The next step is to create the WidgetCollection class.

To create the WidgetCollection class

  1. From the Project menu, choose Add Class. In the Add New Item dialog box, name your class WidgetCollection.vb for Visual Basic and WidgetCollection.cs for Visual C#. The code editor for the WidgetCollection class opens.
  2. In the code editor, add code to cause the class to inherit from CollectionBase, as in this example:
    ' Visual Basic
    Public Class WidgetCollection
       Inherits System.Collections.CollectionBase
    End Class
    
    // C#
    public class WidgetCollection : System.Collections.CollectionBase
       {
       }
    
  3. From the File menu, choose Save All.

You have now created your WidgetCollection class. Because this class inherits from CollectionBase, it already has much of the collection functionality implemented. There is a Clear method to clear the collection and a Count property that keeps track of the number of current members. Additionally, there is a Protected object called List, which you use to keep track of your widgets. But there is no Add method, no Remove method, and no Item property. The implementation of these is left up to the developer.

Implementing the Add and Remove Methods

You will now implement the Add method so that WidgetCollection will add only Widget objects.

To implement the Add method

  1. Add the following code to your WidgetCollection class, beneath the class statement in C#, or the Inherits statement in Visual Basic:
    ' Restricts to Widget types, items that can be added to the collection.
    Public Sub Add(ByVal awidget As Widget)
       ' Invokes Add method of the List object to add a widget.
       List.Add(aWidget)
    End Sub
    
    // C#
    // Restricts to Widget types, items that can be added to the collection
    public void Add(Widget aWidget)
    {
       List.Add(aWidget);
    }
    

    In this method, you restrict to Widget types the items that can be added to the List object through the argument taken by the Add method. Though the List object can accept any type of object, this method prohibits any objects but Widget types from being added, and acts as a "wrapper" around the List object.

  2. From the File menu, choose Save All.

You now have a way to add widgets to your collection. You must now implement a way to remove them. You will do this in a manner similar to the way you created the Add method, by creating a Remove method that accepts an index as an argument and in turn calls the List.RemoveAt method.

To implement the Remove method

  1. Beneath the Add method, add the following code:
    ' Visual Basic
    Public Sub Remove(ByVal index as Integer)
       ' Check to see if there is a widget at the supplied index.
       If index > Count - 1 Or index < 0 Then
          ' If no widget exists, a messagebox is shown and the operation is 
          ' cancelled.
          System.Windows.Forms.MessageBox.Show("Index not valid!")
       Else
       ' Invokes the RemoveAt method of the List object.
          List.RemoveAt(index)
       End If
    End Sub
    
    // C#
    public void Remove(int index)
    {
       // Check to see if there is a widget at the supplied index.
       if (index > Count - 1 || index < 0)
          // If no widget exists, a messagebox is shown and the operation 
          // is cancelled.
          {
             System.Windows.Forms.MessageBox.Show("Index not valid!");
          }
       else
          {
             List.RemoveAt(index); 
          }
    }
    

    This method accepts an integer value for the index argument. If the value is valid, it is passed to the RemoveAt method of the List object, thereby removing the item at the indicated index from the collection.

  2. From the File menu, choose Save All.

Implementing the Item Property

You need to implement one final piece in order to complete basic collection functionality, and that is the Item property. The Item property allows you to obtain a reference to an object in your collection by referring to the index. Since you already have an Add method to add members to the collection, Item will be a ReadOnly property in this demonstration, though it need not be in other contexts. Because C# does not allow properties to have parameters, you will implement Item as a method if you are using C#.

To implement the Item property

  1. Beneath the Sub Remove method, add the following code:
    ' This line declares the Item property as ReadOnly, and 
    ' declares that it will return a Widget object.
    Public ReadOnly Property Item(ByVal index as Integer) As Widget
       Get
          ' The appropriate item is retrieved from the List object and 
          ' explicitly cast to the Widget type, then returned to the 
          ' caller.
          Return CType(List.Item(index), Widget)
       End Get
    End Property
    
    // C#
    public Widget Item(int Index)
    {
       // The appropriate item is retrieved from the List object and
       // explicitly cast to the Widget type, then returned to the 
       // caller.
       return (Widget) List[Index];
    }
    

    In collections, the syntax Collection.Item(0) and Collection(0) are frequently interchangable. If you want to your collection to support this syntax, you should make the Item property the Default property (for Visual Basic) or implement an indexer (in C#). For more information, see Default Properties for Your Components.

  2. From the File menu, choose Save All.

You have now implemented basic collection functionality in your class. You have implemented methods to add and remove widgets from the collection, and you have implemented a property that returns a Widget reference to the appropriate item. In this next section, you will test your WidgetCollection class.

Testing the Project

Now that your WidgetCollection class is complete, it is time to test the functionality. To do this, you will create a simple Windows application that will add, remove, and loop through the widgets in your collection.

To create the test project

  1. In Solution Explorer, right-click Form1, then click View Designer on the shortcut menu.

    The designer for Form1 opens.

  2. Using the Toolbox, add two Label controls, two TextBox controls, and three Button controls to Form1.
  3. Set the properties as follows:
    ControlPropertyValue
    Label1Text"Widget Name"
    Label2Text"Widget Index"
    TextBox1Text""
    TextBox2Text""
    Button1Text"Add a Widget"
    Button2Text"Remove a Widget"
    Button3Text"Review Widgets"

    In the design of your form, Label1 should label TextBox1, and Label2 should Label TextBox2.

  4. In the Form Designer, right-click WidgetTest and choose View Code.

    The Code Editor for WidgetTest opens.

  5. In the Code Editor, locate the line Inherits line (Visual Basic) or the class line (Visual C#). Immediately beneath it, type the following code:
    ' Visual Basic
    ' Creates a WidgetCollection object.
    Dim myWidgetCollection as New WidgetCollection()
    
    // C#
    WidgetCollection myWidgetCollection = new WidgetCollection();
    
  6. In the designer, double-click button1, which now reads "Add a Widget".
  7. In the button1_Click event handler, add code to add a new widget to the collection and set the name of this widget to the value of textBox1.
    ' Visual Basic
    If textbox1.Text = "" Then
       MessageBox.Show("Please name your widget.")
    Else
       ' Declares and instantiates a new widget.
       Dim aWidget as New Widget()
       ' Sets the Name field of the new widget.
       aWidget.Name = textBox1.Text
       ' Adds the new widget to the collection.
       myWidgetCollection.Add(aWidget)
       ' Updates textBox2 with the index of the widget that was added.
       ' The index of a zero-based collection is Count property minus 1.
       textBox2.Text = (myWidgetCollection.Count - 1).ToString()
    End If
    
    // C#
    if (textBox1.Text == "")
       MessageBox.Show("Please name your widget.");
    else
    {
       // Declares and instantiates a new widget.
       Widget aWidget = new Widget();
       aWidget.Name = textBox1.Text;
       // Adds the new widget to the collection
       myWidgetCollection.Add(aWidget);
       // Updates textbox2 with the index of the widget that was added.
       // The index of a zero-based collection is Count property minus 1
       textBox2.Text = (myWidgetCollection.Count -1).ToString();
    }
    
  8. In the button2_Click event handler, add code to remove the widget at the index specified in textBox2.
    ' Visual Basic
    Try
       myWidgetCollection.Remove(CInt(textBox2.Text))
    Catch ex as System.InvalidCastException
       MessageBox.Show("You have attempted to perform an invalid cast")
    End Try
    // C#
    try
    {
       myWidgetCollection.Remove(int.Parse(textBox2.Text));
    }
    catch (System.InvaldiCastException ex)
    {
       MessageBox.Show("You have attempted to perform an invalid cast");
    }
    

    Note that you while you must provide error handling to catch any System.InvalidCastException that might be thrown as the result of an invalid character in the textbox, there is no need to check if a valid value for the index exists in textBox2, because the WidgetCollection.Remove method checks this automatically.

  9. In the button3_Click event handler, write code to cycle through all members of the collection and sequentially display their names in a message box.
    ' Visual Basic
    Dim counter as Integer
    For counter = 0 to myWidgetCollection.Count - 1
       MessageBox.Show(myWidgetCollection.Item(counter).Name)
    Next
    
    // C#
    int counter;
    for(counter = 0; counter <= myWidgetCollection.Count - 1; counter++)
    {
       MessageBox.Show(myWidgetCollection.Item(counter).Name);
    }
    

    You can also use For Each...Next to cycle through the members of your collection.

  10. In Solution Explorer, right-click WidgetProject and choose Properties. The WidgetProject Property Page opens. Under Startup Object, choose WidgetProject.Form1 from the menu and click OK to close the page.

You will now run your test application. You will test the Add method, the Remove method, and the retrieval of Widget objects from the collection.

To test the collection

  1. In the Widget Name text box, type Widget0 and click the Add a Widget button. Repeat this two times, substituting Widget1 and Widget2 for Widget0.

    Three widgets have now been added to the collection.

  2. Click the Review Widgets button.

    The name of each widget successively appears in a message box.

  3. In the Widget Index text box, type 1 and click the Remove a Widget button.

    The widget at index 1 is removed. The index is updated dynamically, so that the widget that previously occupied index 2, now occupies index 1.

  4. Click the Review Widgets button.

    The name of each Widget is again successively displayed in a message box. Note that "Widget1" no longer displays, as it has been removed from the collection.

In this walkthrough, you learned how to implement basic collection functionality by inheriting from the System.Collections.CollectionBase class. You learned how to strongly type your collection, and how to implement the Add and Remove methods and the Item property. For more information on the base classes available to you for the creation of collection classes, see System.Collections Namespace.

See Also

System.Collections Namespace | Object Management with Collections | Using Collections In Classes

Show:
© 2014 Microsoft