Home

C++/CLI Collections:
The ICollection Interface

 

Introduction

One of the primary pieces of information you should always provide about a collection is the number of items it is (currently) holding. When creating a collection class, to prepare it to provide this valuable information, you can (should) implement an interface named ICollection. The ICollection interface is defined in the System::Collections namespace. This means that, if you are creating a class that implements it, you should include this namespace in the file. Here is an example:

using namespace System::Collections;

public ref class CCollection : public ICollection
{
};

Implementing ICollection

To assist you with keeping track of the number of items in a collection, the ICollection interface is equipped with a property named Count, which you must implement. To do this, you can create a private member variable that will actually keep a count of the number of items. The Count property can then be used to communicate this information to the clients of the class. Here is an example:

public ref class CCollection : public ICollection
{
private:
    int nbrOfStudents;

public:
    CCollection();

    virtual property int Count
    {
	int get() { return nbrOfStudents; }
    }
};

CCollection::CCollection()
{
    nbrOfStudents = 0;
}

The ICollection interface also allows its implementer to copy some of its items to an array. To provide this functionality, the interface is equipped with a method named CopyTo. The syntax of this method is:

void CopyTo(Array ^ array, int index);

This method takes two arguments. The first argument is the array that will receive the items. The second argument is the index of the item from where the copying operation will begin. Here is an example:

public ref class CCollection : public ICollection
{
private:
    int nbrOfItems;
    array<double> ^ numbers;

public:
    CCollection();

    virtual property int Count
    {
        int get() { return nbrOfItems; }
    }

    virtual void CopyTo(Array ^, int);
};

CCollection::CCollection()
{
    nbrOfItems = 0;
    numbers = gcnew array<double>(5);
}

void CCollection::CopyTo(Array ^ items, int index)
{
    array<double> ^ nbrs = gcnew array<double>(Count);

    for(int i = 0; i < Count; i++)
        nbrs[i] = numbers[i];
    items = nbrs;
}

If you create a collection class, you can provide the ability to enumerate its items. When this is done, some time to time, you will want to identify or to know what item is currently being accessed. In case other collection classes are using the same function at the time you are accessing this information, you should an object that is responsible for synchronizing the collection. To do this in your ICollection-based class, you must implement a property named SyncRoot. This property must return an Object handle. Here is an example:

public ref class CCollection : public ICollection
{
private:
    int nbrOfItems;

public:
    . . . No Change

    virtual property Object ^ SyncRoot
    {
        Object ^ get() { return this; }
    }
};

Besides the ability to specify the number of items in a collection, a class that implements the ICollection interface must retrieve a value that indicates whether its items is synchronized. To give this information, you must implements a Boolean property named IsSynchronized. Here is an example:

public ref class CCollection : public ICollection
{
private:
    int nbrOfItems;

public:
    . . . No Change

    virtual property bool IsSynchronized
    {
        bool get() { return false; }
    }
};

ICollection extends the IEnumerable interface. This means that you should be able to use for each in your ICollection-based class but you must create the functionality yourself, which is done by implementing the GetEnumerator() method. Even if you don't want to support this feature, you still must provide at least a skeleton for this method. Here is an example:

using namespace System;
using namespace System::Collections;

public ref class CCollection : public ICollection
{
private:
    int nbrOfItems;

public:
    . . . No Change

    virtual IEnumerator ^ GetEnumerator();
};

IEnumerator ^ CCollection::GetEnumerator()
{
    return nullptr;
}
 

Previous Copyright © 2007-2012 FunctionX Home