I’m having problems implementing IEnumerable<T> in my custom collection class in C++/CLI. Here is the relevant part of the code:
using namespace System::Collections::Generic;
ref class MyCollection : IEnumerable<MyClass^>
{
public:
MyCollection()
{
}
virtual IEnumerator<MyClass^>^ GetEnumerator()
{
return nullptr;
}
};
When compiled, this results in the following errors:
error C2392:
‘System::Collections::Generic::IEnumerator
^MyCollection::GetEnumerator(void)’:
covariant returns types are not
supported in managed types, otherwise
‘System::Collections::IEnumerator
^System::Collections::IEnumerable::GetEnumerator(void)’
would be overridden error C3766:
‘MyCollection’ must provide an
implementation for the interface
method
‘System::Collections::IEnumerator
^System::Collections::IEnumerable::GetEnumerator(void)’
This makes sense, since IEnumerable<T> derives from IEnumerable. However, I’m not sure how to fix this compile error. If this was C#, I would implicitly implement IEnumerable, however I’m not sure how to do that in C++/CLI (if that’s even possible) like this:
class MyCollection : IEnumerable<MyClass>
{
public MyCollection()
{
}
public IEnumerator<MyClass> GetEnumerator()
{
return null;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
If I do add an implementation of IEnumerable::GetEnumerator(), the compiler complains about two methods that differ only by return type (which also makes sense).
So, how do I implement IEnumerable<T> in a C++/CLI class?
You must provide an explicit implementation of the non-generic GetEnumerator() method and include the non-generic namespace:
Update: As mentioned in the comments, the explicit version of GetEnumerator must be named different to avoid name clash, thus I’ve named it EnumerableGetEnumerator.
Similarly, in C# you would have to do it like this: