SUMMARY
This article demonstrates how to implement custom
collections in Visual C++ through the use of managed extensions. The .NET
Framework base class libraries offer a formal definition of a collection, the
System.Collections.ICollection interface.
back to the top
Implementing the ICollection Interface in a Custom Class
The
ICollection interface inherits from the
IEnumerable interface. The
ICollection interface defines a
CopyTo method and three read-only properties:
IsSynchronized,
SyncRoot, and
Count.
ICollection inherits the
GetEnumerator method from the
IEnumerable interface. A custom collection class should implement the
ICollection interface.
To implement the
ICollection interface, you would take the following steps:
- Implement a CustomCollection class that is derived from ICollection. For simplicity, declare an integer array to hold integer items
that are initialized with three integers. Also declare a Ct count variable that is set to "3", the size of the
array.
- Implement the CopyTo method, which takes an integer array and an index as parameters.
This method copies the items in a collection to the array and starts at the
index that is passed.
- Implement the GetEnumerator method, which is inherited by ICollection from IEnumerable. The GetEnumerator method returns an object that implements the IEnumerable interface.
- Implement the read-only properties IsSynchronized, SyncRoot, and Count.
back to the top
Implementing an Enumerator Object for the GetEnumerator Method
- Implement an Enumerator class that is derived from IEnumerator to support enumeration of the CustomCollection class.
- Declare the intArr private integer array to hold the elements of the CustomCollection class when the GetEnumerator method is called. The Cursor field member holds the current position during
enumeration.
- Add a constructor with intArr as a parameter to initialize the intArr member.
- Implement the Reset and MoveNext methods. (Reset sets the cursor to "-1", and MoveNext moves the cursor to the next element.) MoveNext returns True if enumeration is successful.
- Implement the read-only property Current,
which returns the item that the cursor is pointing to. If the cursor is not
pointing to a valid item, throw an InvalidOperationException.
back to the top
Iterating Through the Custom Collection
Visual C++ .NET does not support the
foreach construct to iterate through the collection. But the following
code does the equivalent:
IEnumerator* ie=MyCol->GetEnumerator();
while (ie->MoveNext())
{
Console::WriteLine(ie->Current->ToString());
}
back to the top
Complete Code Sample
//compiler option: cl /clr
#using <mscorlib.dll>
using namespace System;
using namespace System::Collections;
__gc class Enumerator : public IEnumerator
{
int intArr __gc [];
int Cursor;
public:
Enumerator(int intarr __gc[])
{
this->intArr = intarr;
Cursor = -1;
}
void IEnumerator::Reset()
{
Cursor = -1;
}
bool IEnumerator::MoveNext()
{
if (Cursor < intArr->Length)
Cursor++;
return(!(Cursor == intArr->Length));
}
Object* IEnumerator::get_Current()
{
if((Cursor < 0) || (Cursor == intArr->Length))
throw new InvalidOperationException();
return __box(intArr[Cursor]);
}
};
__gc class CustomCollection : public ICollection
{
int intArr __gc[] ;
int Ct;
public:
CustomCollection()
{
intArr = new int __gc [3];
intArr[0]= 1;
intArr[1]= 5;
intArr[2]= 9;
Ct=3;
}
void ICollection::CopyTo(Array* myArr, int index)
{
//foreach (int i in intArr)
for(int i=0;i<intArr->Length;i++)
{
myArr->SetValue(__box(intArr[i]),index);
index ++;
}
}
IEnumerator* IEnumerable::GetEnumerator()
{
return new Enumerator(intArr);
}
//The IsSynchronized Boolean property returns True if the
//collection is designed to be thread safe; otherwise, it returns False.
bool ICollection::get_IsSynchronized()
{
return false;
}
//The SyncRoot property returns an object, which is used for synchronizing
//the collection. This returns the instance of the object or returns the
//SyncRoot of other collections if the collection contains other collections.
//
Object* ICollection::get_SyncRoot()
{
return this;
}
//The Count read-only property returns the number
//of items in the collection.
int ICollection::get_Count()
{
return Ct;
}
};
// This is the entry point for this application
int main()
{
CustomCollection* MyCol = new CustomCollection();
IEnumerator* ie=MyCol->GetEnumerator();
while (ie->MoveNext())
{
Console::WriteLine(ie->Current->ToString());
}
return 0;
}
Note You must add the common language runtime support compiler option (
/clr:oldSyntax) in Visual C++ 2005 to successfully compile this code sample.
To do this, follow these steps:
- Click Project, and then click ProjectName Properties.
Note ProjectName represents the name of the project. - Expand Configuration Properties, and then click General.
- Click to select Common Language Runtime Support, Old Syntax (/clr:oldSyntax) in the Common Language Runtime support project setting on the right pane, click Apply, and then click OK.
For more information about the common language runtime support compiler options, visit the following Microsoft Web site:
back to the top