WindowsDevCenter.com
oreilly.comSafari Books Online.Conferences.

advertisement


AddThis Social Bookmark Button

Implementing Custom Data Bindable Classes: IList
Pages: 1, 2, 3

ICollection

Now all of the members of IList have been implemented, so let's turn our attention to the three members of the ICollection interface. Because thread safety is beyond the scope of this article just leave IsSynchronized and SyncRoot alone. The Count method is easy enough to code:



public int Count { get { return count; } }

That leaves us with the CopyTo method, which takes a one-dimensional array passed in by reference and loads it up with values from the linked list. The method expects an index parameter for the starting position, which must be within the bounds of the collection or else an ArgumentOutOfRangeException is thrown. Also, if the array passed in is not large enough to hold the range of elements in the collection, then an ArgumentException is thrown:


public void CopyTo(Array array, int index) 
{
  Node tempNode = head;
  if (index < 0 || index >= count) 
  {
    throw new 
      ArgumentOutOfRangeException("The index is out of range.");
  }
  if (array.Length < (this.Count - index) + 1) 
  {
    throw new ArgumentException("Array " +
      "cannot hold all values.");
  }
  // advance to starting index position
  for(int i = 0; i < index; ++i) 
  {
    tempNode = tempNode.Next;
  }
  // iterate through list adding to array
  int j = 0;
  for(int i = index; i < count; ++i) 
  {
    array.SetValue(tempNode.Item, i);
    tempNode = tempNode.Next;
    j++;
  }
}

IEnumerator

The last thing we have to do is implement the GetEnumerator method. I won't devote the space to explain it here since the second article in this series covered it in depth. Basically, you just have to return an IEnumerator instance:


public IEnumerator GetEnumerator() 
{
  return new ListEnumerator(this);
}

public class ListEnumerator : IEnumerator 
{
  private int idx = -1;
  private  LinkedList linkedList;
  public ListEnumerator(LinkedList linkedList) 
  {
    this.linkedList = linkedList;
  }
  public void Reset() 
  {
    idx = -1;
  }
  public object Current 
  {
    get 
    {
      if (idx > -1)
        return 
          linkedList[idx];
      else
        return -1;
    }
  }
  public bool MoveNext() 
  {
    idx++;
    if (idx < linkedList.Count)
      return true;
    else
      return false;
  }
}

The singly linked list now fully implements the IList interface. It supports enumeration of its elements with the foreach statement. It allows for complex data binding with .NET iterative or list controls such as a DataGrid, a Repeater or a DropDownList. And best of all, by implementing against IList, our linked list class has now become a data source that can be used predictably throughout the project.

Stressing LinkedList

Let's stress the new class. In a console application that references the LinkedList class, instantiate it and populate it with five string values:


LinkedList myList = new LinkedList();
myList.Add("Alpha");
myList.Add("Beta");
myList.Add("Gamma");
myList.Add("Delta");
myList.Add("Epsilon");
Console.WriteLine("Loaded " + myList.Count.ToString() + 
                  " items into list.");

If you run the program you should see the message "Loaded 5 items into list." Since our class now supports the foreach statement we can easily enumerate the elements in the collection and write them out to the console:


foreach (object o in myList) {
    string s = (string)o;
    Console.WriteLine(s);
}

If we want to remove an item from the middle (the "Gamma" string value at index position 2) we would call:

myList.RemoveAt(2);

Now let's remove the first and last elements from the collection and print out the remaining elements to the console:


myList.RemoveAt(0);
myList.Remove("Epsilon");
foreach (object o in myList) {
  string s = (string)o;
  Console.WriteLine(s);
}

The two remaining strings "Beta" and "Delta" print out to the console.

Conclusion

In this article we took a simple singly linked list and turned it into a robust .NET collection class. We did that by implementing against the IList interface, which requires us to implement certain methods and properties that guarantee our class will behave the way a collection class should in the .NET Framework. You now have everything you need to implement IList in your own projects.

Related Links

James Still James Still is an experienced software developer in Portland, Oregon. He collaborated on "Visual C# .NET" (Wrox) and has immersed himself in .NET since the Beta 1 version was released.


Return to ONDotnet.com