C# Source Code: Creating a custom enumerator class using the IEnumerator interface
[
Home
|
Contents
|
Search
|
Reply
| Previous | Next ]
C# Source Code
Creating a custom enumerator class using the IEnumerator interface
By:
Andrew Baker
Email (spam proof):
Email the originator of this post
Date:
Wednesday, April 07, 2004
Hits:
955
Category:
General/Framework
Article:
Below is an example which demonstrates how to make a custom enumeration class and shows the two different methods of loop over a collection class using the IEnumerator interface. using System; using System.Collections; namespace vbUsers.Enumerators { class EnumeratorDemo { //Demonstrates how to use a class with a custom enumerator [STAThread] static void Main(string[] args) { //Create collection class adding new items to it School MySchool = new School(10); MySchool.Add("Andrew",32); MySchool.Add("Peter",19); MySchool.Add("Philip",28); MySchool.Add("Shannon",40); //Loop over collection using foreach loop Console.WriteLine("-----"); foreach(School.KeyItemPair student in MySchool) { Console.WriteLine("Name: " + student.key + ". Age: " + student.item); } //Loop over collection by calling GetEnumerator Console.WriteLine("-----"); IEnumerator enumerator = MySchool.GetEnumerator(); while(enumerator.MoveNext()==true) { School.KeyItemPair student = (School.KeyItemPair)enumerator.Current; Console.WriteLine("Name: " + student.key + ". Age: " + student.item); } //Pause Console.ReadLine(); } } //Class containing a collection of school children public class School: IEnumerable { //Public Event to notify any enumerators that the collection has been changed and they are now invalid public delegate void CollectionChangedEvent(object sender, EventArgs e); public event CollectionChangedEvent ChangeEvent; //Declare event arguments private EventArgs zArgs = new EventArgs(); //Storage variables protected KeyItemPair[] zoItems; protected int ziCount; //Constructor public School(int IntialSize) { //Size the internal array to store the key value pairs zoItems = new KeyItemPair[Math.Max(IntialSize,1)]; //Store the current no. of stored items ziCount = 0; } //Return an instance of the enumerator public IEnumerator GetEnumerator() { return new SchoolEnumerator(this); } //Expose the string Indexer public object this[string key] { get{ return (object)KeyToObject(key);} set{ Add(key,value);} } //Expose the int Indexer public KeyItemPair this[int item] { get{ return zoItems[item];} } //Returns the number of stored items public int Count() { return ziCount; } //Adds a key value pair to the internal array public void Add(string key, object item) { int ExistingKeyIndex = KeyPosition(key); if(ExistingKeyIndex > - 1) { //Key exists in array, update item zoItems[ExistingKeyIndex] = new KeyItemPair(key,item); } else { if(ziCount == zoItems.Length) { ResizeArray(); } zoItems[ziCount] = new KeyItemPair(key,item); ziCount++; } RaiseCollectionChangedEvent(); } //Increases the size of the array to store more items protected void ResizeArray() { ziCount += 5; KeyItemPair[] OldArray = zoItems; zoItems = new KeyItemPair[ziCount]; OldArray.CopyTo(zoItems,0); } //Returns the Object given the key protected object KeyToObject(string key) { for(int n = 0;n < ziCount;++n) { if(zoItems[n].key == key) { return zoItems[n].item; } } return null; } //Returns the position of the object within the internal array, given the key protected int KeyPosition(string key) { for(int Position = 0; Position < ziCount; ++Position) { if(zoItems[Position].key == key) { return Position; } } return -1; } //Value Type Structure to store key value pairs public struct KeyItemPair { public KeyItemPair(string sKey, object oItem) { key = sKey ; item =oItem; } public object item; public string key; } protected void RaiseCollectionChangedEvent() { if(ChangeEvent!=null) { //The event is being listened for ChangeEvent(this,zArgs); } } public void AddListener(CollectionChangedEvent evt) { ChangeEvent += evt; } public void RemoveListener(CollectionChangedEvent evt) { ChangeEvent -= evt; } } //Class containing custom implimentation of enumerator public class SchoolEnumerator: IEnumerator { protected School zschool; protected Boolean zbInvalidated; protected int zlCurIndex; protected School.CollectionChangedEvent zChangeEvt; //Destructor ~SchoolEnumerator() { //Remove listener if(zschool!=null) zschool.RemoveListener(zChangeEvt); } public SchoolEnumerator(School sch) { zschool = sch; zlCurIndex = -1; zbInvalidated = false; //Add our event listener (in case the collection changes while we are enumerating it) zChangeEvt = new School.CollectionChangedEvent(InvalidateHandler); sch.AddListener(zChangeEvt); } public object Current { get { if(zbInvalidated==true || zlCurIndex == zschool.Count()) { throw new InvalidOperationException(); } return zschool[zlCurIndex]; } } public bool MoveNext() { if(zbInvalidated==true || zlCurIndex == zschool.Count()) { throw new InvalidOperationException(); } zlCurIndex++; if(zlCurIndex == zschool.Count()) return false; else return true; } public void Reset() { if (zbInvalidated) throw new InvalidOperationException(); zlCurIndex=-1; } private void InvalidateHandler(object sender,EventArgs e) { zbInvalidated = true; } } }
Terms and Conditions
Support this site
Download a trial version of the best FTP application on the internet