如何为2种不同类型实现通用接口IEnumerable?

时间:2018-01-19 13:18:38

标签: generics c++-cli

我必须在C ++ / CLI中为2种不同的类型实现IEnumerable接口吗?

IEnumerable<PmaIf::ICounterValue^>^

IEnumerator<System::String^>^

如果我尝试为这两种类型实现GetEnumerator,我会收到错误,说只有不同的返回类型才能重载方法。

2 个答案:

答案 0 :(得分:1)

您的班级不能有两个不同的公开GetEnumerator。您需要做的是使用显式接口实现。使用显式接口实现,这些方法在您的类中将具有不同的名称,但每个都将为两个接口之一实现GetEnumerator

以下是语法:

public ref class PmaThing : public IEnumerable<PmaIf::ICounterValue^>, IEnumerable<System::String^>
{
public:
    virtual IEnumerator<PmaIf::ICounterValue^>^ GetCounterEnumerator() sealed = 
            IEnumerable<PmaIf::ICounterValue^>::GetEnumerator;

    virtual IEnumerator<System::String^>^ GetStringEnumerator() sealed = 
            IEnumerable<System::String^>::GetEnumerator;
}

注意:我没有用编译器检查我的语法,但我的回忆是在进行显式接口实现时需要virtualsealed

答案 1 :(得分:0)

好吧,我不打算评论这是否是一个好主意,我会给你这样做的语法。下面的示例通常用作int的IEnumerable。如果强制转换为IEnumerable为double,它将使用双枚举器。如果您的类为两个不同的T实现了IEnumerable of T接口,则必须明确实现其中一个,这意味着只有在通过接口访问时才能访问实现。

以下是头文件:

using namespace System;

namespace DoubleEnumerableTest 
{
    public ref class EnumerableAsIntAndDouble : 
        System::Collections::Generic::IEnumerable<int>, 
        System::Collections::Generic::IEnumerable<double>
    {
    public:
        //the class by default (when not cast to IEnumerable<double>) will 
        //use this enumerator
        virtual System::Collections::Generic::IEnumerator<int>^ GetEnumerator() sealed;
    private:
        //non generic enumerator will be of integers
        virtual System::Collections::IEnumerator^ GetNonGenericEnumerator() 
           sealed = System::Collections::IEnumerable::GetEnumerator;

        //Only accessible when cast to IEnumerable<double>
        virtual System::Collections::Generic::IEnumerator<double>^ 
          GetDoubleEnumerator() sealed = 
             System::Collections::Generic::IEnumerable<double>::GetEnumerator;
    };
}

以下是实现文件(以及实际创建所需枚举器的代码):

System::Collections::Generic::IEnumerator<int>^ 
    DoubleEnumerableTest::EnumerableAsIntAndDouble::GetEnumerator()
{
    // Create enumerator for type int here
    throw gcnew System::NotImplementedException();

}

System::Collections::IEnumerator^ 
    DoubleEnumerableTest::EnumerableAsIntAndDouble::GetNonGenericEnumerator()
{
    //non-generic enumerator delegates to integer enumerator
    return GetEnumerator();
}

System::Collections::Generic::IEnumerator<double>^ 
     DoubleEnumerableTest::EnumerableAsIntAndDouble::GetDoubleEnumerator()
{
    //Create enumerator for type double in here
    throw gcnew System::NotImplementedException();
}