Home

An Enumerable Collection

 

Introduction

The IEnumerator interface is used to set up a collection for enumeration. The IEnumerator doesn't provide the functionality necessary to use foreach. The next step is to implement another interface called IEnumerable. While the IEnumerator interface is used to identify the class that holds each value that will be visited, the IEnumerable interface is used to communicate with the collection whose items will be enumerated. For this reason, when implementing this class, you should provide the means of accessing the external collection. This can be done by passing a collection of the class that holds the values, to a constructor of the IEnumerable implementer.

 

Getting the Enumerator

To implement the IEnumerable interface, start by deriving a class from it. While the class implemented by the IEnumerator interface represents an object, the class that implements the IEnumerable is a collection. Here is an example:

public class Enumerable : IEnumerable
{
}

Notice that the new class doesn't know what collection it will be asked to enumerate. For this reason, in the new class, you should declare a member variable of the class that holds the values that will be enumerated. If the collection is array-based, you can create the field as follows:

public class Enumerable : IEnumerable
{
    private double[] numbers;
}

Eventually, when instantiating the IEnumerable implementer, you will need to pass it a collection of values. To make this possible, you can create a method in the new class and pass that collection of objects. Here is an example:

public class Enumerable : IEnumerable
{
    private double[] numbers;

    public void Identify(double[] values)
    {
    }
}

In this method, you can assign the member variable to the argument. You should also assign each member of the argument to its equivalent of the member of the argument. This can be done as follows:

public class Enumerable : IEnumerable
{
    private double[] numbers;

    public void Identify(double[] values)
    {
        numbers = values;
        for (int i = 0; i < values.Length; i++)
            numbers[i] = values[i];
    }
}

To support the use of the foreach loop, the IEnumerable interface is equipped with (only) a method named GetEnumerator that you must implement. The IEnumerable.GetEnumerator() method returns an IEnumerator object. When implementing this method, you can return an object of the class that implements the IEnumerator interface, passing it the collection that was declared in the IEnumerable implementer. This can be done as follows: 

public class Enumerable : IEnumerable
{
    private double[] numbers;

    public void Identify(double[] values)
    {
        numbers = values;
        for (int i = 0; i < values.Length; i++)
            numbers[i] = values[i];
    }

    public IEnumerator GetEnumerator()
    {
        return new Enumerator(numbers);
    }
}

Practical Learning Practical Learning: Getting the Enumerator

  1. To create a new class, in the Class View, right-click FlowerShop5 -> Add -> Class...
  2. Set the Name of the class to Flowers and click Add
  3. Change the file as follows:
     
    using System;
    using System.Collections;
    
    namespace FlowerShop5
    {
        public class Flowers : IEnumerable
        {
            private FlowerInventory items;
    
            public void Locate(FlowerInventory list)
            {
                items = new FlowerInventory();
    
                for (int i = 0; i < list.Count; i++)
                    this.items.Add(list.Get(i));
            }
    
            public IEnumerator GetEnumerator()
            {
                FlowerIdentifier fid = new FlowerIdentifier();
    
                fid.Identify(items);
                return fid; 
            }
        }
    }
  4. Save the file

Using foreach

After implementing the IEnumerator and the IEnumerable interfaces, you can then use the foreach loop. To start, you must prepare the collection and its items for processing. Here is an example:

class Program
{
    static int Main(string[] args)
    {
        double[] numbers = new double[5];
        numbers[0] = 224.52;
        numbers[1] = 60.48;
        numbers[2] = 1250.64;
        numbers[3] = 8.86;
        numbers[4] = 1005.36;

        return 0;
    }
}

To enumerate the collection, declare a variable based on the implementer of the IEnumerable and pass the collection to its constructor. Once this is done, you can then user the foreach. Here is an example:

using System;
using System.Collections;

public class Enumerator : IEnumerator
{
    private double[] numbers;
    private int cur;

    public Enumerator(double[] list)
    {
        this.numbers = list;
        cur = -1;
    }

    public Object Current
    {
        get { return numbers[cur]; }
    }

    public void Reset()
    {
        cur = -1;
    }

    public bool MoveNext()
    {
        cur++;
        if (cur < numbers.Length)
            return true;
        else
            return false;
    }
}

public class Enumerable : IEnumerable
{
    private double[] numbers;

    public void Identify(double[] values)
    {
        numbers = values;
        for (int i = 0; i < values.Length; i++)
            numbers[i] = values[i];
    }

    public IEnumerator GetEnumerator()
    {
        return new Enumerator(numbers);
    }
}

class Program
{
    static int Main(string[] args)
    {
        double[] numbers = new double[5];
        numbers[0] = 224.52;
        numbers[1] = 60.48;
        numbers[2] = 1250.64;
        numbers[3] = 8.86;
        numbers[4] = 1005.36;

        Enumerable coll = new Enumerable();
        
        coll.Identify(numbers);
        foreach (double d in coll)
            Console.WriteLine("Item {0}", d); ;

        return 0;
    }
}

Practical Learning Practical Learning: Using foreach on an Enumerator

  1. Access the Program.cs file and change it as follows:
     
    using System;
    
    namespace FlowerShop5
    {
        class Program
        {
            static int Main(string[] args)
            {
                FlowerInventory fls = new FlowerInventory();
                Flower nice;
    
                nice = new Flower();
                nice.Type = FlowerType.Lilies;
                nice.Color = FlowerColor.White;
                nice.Arrangement = FlowerArrangement.Bouquet;
                nice.UnitPrice = 39.95M;
                fls.Add(nice);
    
                nice = new Flower();
                nice.Type = FlowerType.Daisies;
                nice.Color = FlowerColor.Mixed;
                nice.Arrangement = FlowerArrangement.Bouquet;
                nice.UnitPrice = 40.50M;
                fls.Add(nice);
    
                nice = new Flower();
                nice.Type = FlowerType.Carnations;
                nice.Color = FlowerColor.Lavender;
                nice.Arrangement = FlowerArrangement.Any;
                nice.UnitPrice = 34.85M;
                fls.Add(nice);
    
                nice = new Flower();
                nice.Type = FlowerType.Roses;
                nice.Color = FlowerColor.Pink;
                nice.Arrangement = FlowerArrangement.Bouquet;
                nice.UnitPrice = 29.95M;
                fls.Add(nice);
    
                nice = new Flower();
                nice.Type = FlowerType.Daisies;
                nice.Color = FlowerColor.Yellow;
                nice.Arrangement = FlowerArrangement.Vase;
                nice.UnitPrice = 29.95M;
                fls.Add(nice);
    
                Flowers collection = new Flowers();
                collection.Locate(fls);
    
              Console.WriteLine("//=//=//=//=//=//=//=//=//=//=//=//=//=//=//");
              Console.WriteLine("Total: {0} flower items in current inventory",
                    fls.Count);
              Console.WriteLine("--------------------------------------------");
                Console.WriteLine("Inventory Summary");
                foreach (Flower flr in collection)
                {
                    Console.WriteLine("------------------------");
                    Console.WriteLine("Flower Information");
                    Console.WriteLine("Type:        {0}", flr.Type);
                    Console.WriteLine("Color:       {0}", flr.Color);
                    Console.WriteLine("Arrangement: {0}", flr.Arrangement);
                    Console.WriteLine("Unit Price:  {0:F}", flr.UnitPrice);
                }
              Console.WriteLine("//=//=//=//=//=//=//=//=//=//=//=//=//=//=//");
                return 0;
            }
        }
    }
  2. Execute the application to see the result:
     
    //=//=//=//=//=//=//=//=//=//=//=//=//=//=//
    Total: 5 flower items in current inventory
    --------------------------------------------
    Inventory Summary
    ------------------------
    Flower Information
    Type:        Lilies
    Color:       White
    Arrangement: Bouquet
    Unit Price:  39.95
    ------------------------
    Flower Information
    Type:        Daisies
    Color:       Mixed
    Arrangement: Bouquet
    Unit Price:  40.50
    ------------------------
    Flower Information
    Type:        Carnations
    Color:       Lavender
    Arrangement: Any
    Unit Price:  34.85
    ------------------------
    Flower Information
    Type:        Roses
    Color:       Pink
    Arrangement: Bouquet
    Unit Price:  29.95
    ------------------------
    Flower Information
    Type:        Daisies
    Color:       Yellow
    Arrangement: Vase
    Unit Price:  29.95
    //=//=//=//=//=//=//=//=//=//=//=//=//=//=//
    Press any key to continue . . .
  3. Close the DOS window
 

Previous Copyright © 2006 FunctionX, Inc. Next