ienumerable


An ienumerable object basically represents a sequence of items. 

It implements the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T> interface.

Ienumerable objects expose enumerators via the “GetEnumerator” method.  This is because the IEnumerable interface extends the IEnumerator interface.

Suppose we have the following class representing a single car.

public class Car
{       
    public string Model;
    public decimal Price;
    //constructor
    public Car(string strModel, decimal decPrice)
    {
        this.Model = strModel;
        this.Price = decPrice;       
    }

Now lets create a class that represents a collection of Car objects.  We inherit the IEnumerable interface so that we can use it in a foreach loop.  The IEnumerable interface has a method “GetEnumerator” which we must implement.  This method returns an enumerator.

public class Autos : IEnumerable
{
    private Car[] _autos;

    //constructor
    public Autos(Car[] carArray)
    {
        //set the length of our private array
        _autos = new Car[carArray.Length];
        //load the private array
        for (int i = 0; i < carArray.Length; i++)
        {
            _autos[i] = carArray[i];
        }
    }

    //Implements the GetEnumerator method of the IEnumerable interface
    //and returns an Enumerator

    IEnumerator IEnumerable.GetEnumerator()
    {
        return new AutosEnum(_autos);
    }

}

An enumerator is a cursor that travels forward-only within the elements of an Ienumerable object.

Enumerators implement the System.Collections.IEnumerator or System.Collections.Generic.IEnumerator<T> interfadces. 

They provide the “MoveNext” method for stepping through the IEnumerable object.

They provide the “Reset” method for initializing the position of the cursor to –1. 

They expose the current item in the sequence via the “Current” property.

Here is a class that implements the IEnumerator interface.  This class is instantiated in our Autos enumerable class.

public class AutosEnum : IEnumerator
{
   public Car[] _autos;

    int enumposition = -1;

    //constructor
    public AutosEnum(Car[] CarList)
    {
        _autos = CarList;
    }

    //Implement the MoveNext method of the IEnumerator interface
    public bool MoveNext()
    {
        enumposition++;
        return (enumposition < _autos.Length);
    }

    //Implement the Reset method of the IEnumerator interface
    public void Reset()
    {
        enumposition = -1;       
    }

    //Implement the Current method of the IEnumerator interface
    public object Current
    {
        get
        {
            try
            {
                return _autos[enumposition];
            }
            catch (IndexOutOfRangeException)
            {
                throw new InvalidOperationException();
            }
        }
    }
}

Now here is a class that tests loading the enumerable with Car objects and using a foreach statement to iterate through the elements:

public class EnumTesterClass
{
    public void TestEnums()
    {
        Car[] carArray = new Car[3]
        {
            new Car("Camry", 28000),
            new Car("Jetta", 24500),
            new Car("Civic", 22000)
        };
        //Autos is my enumerable
        Autos AutosList = new Autos(carArray);

        foreach (Car a in AutosList)
            System.Diagnostics.Debug.WriteLine(a.Model + " " + a.Price);

    }
}

You can also obtain an IEnumerator from an arraylist:

You can just pass the arraylist to a foreach statement to iterate over every element in the arraylist.

However, if you ever need to iterate over a subset of the arraylist you can not use the foreach statement.

In this case, you can obtain the IEnumerator from the arraylist and use that to iterate over your subset of items.

Suppose we have a class that declares an arraylist “CarList” with a loader method “loadcars” that will load 3 items into the arraylist:

public class CarListClass
{
    //Use the Synchronized method to make the arraylist thread safe
    private ArrayList _cars = ArrayList.Synchronized(new ArrayList());

    public ArrayList CarList
    {
        get { return _cars; }
    }

    public void loadcars()
    {
        _cars.Add("Camry");
        _cars.Add("Jetta");
        _cars.Add("Civic");
    }           
}

Here is a tester class to show you how to get an ienumerator from the CarList arraylist:

public class EnumTesterClass2
{
    public void TestEnums()
    {
        CarListClass carlistclass = new CarListClass();
        carlistclass.loadcars();

        //The foreach statement allows you to iterate over every item in the arraylist
        foreach (string strCar in carlistclass.CarList)
            System.Diagnostics.Debug.WriteLine(strCar);

        //In order to iterate over a subset of the arraylist you can use the GetEnumerator method
        IEnumerator carEnum = carlistclass.CarList.GetEnumerator(0,2);

        while (carEnum.MoveNext())
        {
            System.Diagnostics.Debug.WriteLine(carEnum.Current);
        }
    }
}

No comments:

Post a Comment