Search Forum
(57415 Postings)
Search Site/Articles

Archived Articles
712 Articles

C# Books
C# Consultants
What Is C#?
Download Compiler
Code Archive
Archived Articles
Advertise
Contribute
C# Jobs
Beginners Tutorial
C# Contractors
C# Consulting
Links
C# Manual
Contact Us
Legal

GoDiagram for .NET from Northwoods Software www.nwoods.com


              
Printable Version

Developing Collection Classes In .NET
By Yogesh Patange

Collection resembles to grouping together the set of objects with the same characteristics, in programming paradigm it resembles to the set of object instances of the same class. In .NET, class libraries provides the collection interfaces that are used to develop one's own collection classes. The basic functionality for the collections is made available by inheriting the abstract (MustInherit in VB) Class CollectionBase from the System.Collection namespace. The CollectionBase class provides the 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 of the object instances. Other methods such as Add and Remove as well as the Item property requires implementation to be provided.

Steps:
Create the class for which the collection class is to be implemented:
For our discussion we will consider the following class definition.

class Leaf {
 private int intAge;
 private String strName;
       
 // Default Constructor 
 public Leaf() {}

 // gets and sets the age value
 public int Age {
  get {
   return intAge;
  }
  set {
   intAge = value;
  }
 }

 // gets and sets the strName variable
 public string Name {
  get {
   return strName;
  }
  set {
   strName = value;
  }
 }
}
The class leaf has private variables intAge and strName and exposes them through public properties Age and Name to the outside world.
Now let us write the collection class. We will name this class as Leafs.

class Leafs: CollectionBase { }

As the above definition suggests the Leafs class inherits from the CollectionBase abstract class. Inheriting from the CollectionBase class implicitly provides the List collection which is of type IList and which represents a collection of objects that can be individually indexed. The next step is to provide the implementation for the methods in CollectionBase.

Implement the Add, Remove methods and Item property.

// Method implementation from the CollectionBase class
public void Add(Leaf aLeaf){     
 List.Add(aLeaf);
}       

// Method implementation from the CollectionBase class
public void Remove(int index){
 // Check to see if there is a Leaf at the supplied index.
 if (index > Count - 1 || index < 0) {
  // Handle the error that occurs if the valid page index is       
  // not supplied.    
  // This exception will be written to the calling function             
  throw new Exception("Index out of bounds");            
 }        
 List.RemoveAt(index);       
} 
// Method implementation from the CollectionBase class
public Leaf Item(int Index) {     
 // The appropriate item is retrieved from the List object and     
 // explicitly cast to the Leaf type, then returned to the      
 // caller.     
 return (Leaf) List[Index]; 
}
The above procedure will make the full functional collection class for containing the collection instances of your own class definition. We can still improve the handling of the above class, by adding the functionality to support the class to be used with foreach.. in.. construct. For collection class to support the enumeration functionality it can be extended to implement the IEnumerable interface.

Steps:

Extend your Collection class definition to implement IEnumerable interface:

class Leafs: CollectionBase, IEnumerable{}

Every collection is required to return the enumerator interface for the classes that provide the collection enumeration functionality. The GetEnumerator() function form IEnumerable interface returns the Enumerator object for the collection. So we have to define the enumerator object for our collection and then rewrite the IEnumerable.GetEnumerator() function to return the IEnumerator interface. Following is the code snippet for class Enumerator for our Leafs collection and we will name it as LeafEnumerator.

/* Define the Enumeration class to return */        
public class LeafEnumerator: IEnumerator { 
 int nIndex;            
 Leafs collection;            
 public LeafEnumerator(Leafs coll) {                
  collection = coll;                
  nIndex = -1;            
 }
 // Sets the enumerator to its initial position, which is
 // before the first element in the collection.
 public void Reset() { 
  nIndex = -1;
 }
 // Advances the enumerator to the next element of the 
 // collection.            
 public bool MoveNext() {
  nIndex++;                
  return(nIndex < collection.Count);            
 }
 // Gets the current element in the collection.
 public Leaf Current {
  get {                    
   return((Leaf)collection.Item(nIndex));                
  }            
 }            
 // The current property on the IEnumerator interface: 
 object IEnumerator.Current {                
  get {                    
   return(Current);                
  }            
 }        
} // End of class LeafEnumeration
As seen above our LeafEnumerator Class implements the IEnumerator interface. So we have to provide the implementation for the functions Reset, MoveNext and Current. The class LeafEnumerator can exist as separate class in the same assembly or can be inner class in our Leafs collection. It is best practice to have it as the inners class because it will hardly be used directly in application.
Now we will provide the base implementation for the IEnumerable.GetEnumerator() and a new implementation for the function GetEnumerator() in the following manner
// Implement the method GetEnumerator from the interface        
//IEnumerable       
public new LeafEnumerator GetEnumerator() {           
 return new LeafEnumerator(this);        
}        
// Implement the GetEnumerator() method:        
IEnumerator IEnumerable.GetEnumerator() {            
 return GetEnumerator();        
}
And we are done. Now let us test our Collection class. In the following code we
· Create the instance of the collection class.
· Adds the Leafs items to the collection
· Iterates through the collection Items and displays the output on to the console.
class Entry{     
 public static void Main() {         
  Leafs lfc = new Leafs();                 
  Leaf lf = new Leaf();     
  lf.Age = 10;     
  lf.Name = "Paresh";                 
  Leaf lf1 = new Leaf();     
  lf1.Age = 100;     
  lf1.Name = "Sharmili";     
  lfc.Add(lf);     
  lfc.Add(lf1);     
  foreach(Leaf l in lfc) {
   Console.WriteLine("Name : " + l.Name + " Age : " + l.Age);           
  }          
 }       
}
Output displayed at the console:Name : Paresh Age : 10Name : Sharmili Age : 100

It is always a good practice to use collections over arrays when dealing with the reference data types. It avoids most of the runtime error that can occur when using the arrays. Also it relives the programmer from tracking for the array index being invalid. At the same time it makes the code look cleaner and more readable.