C#实现两个不同的通用接口

时间:2009-08-11 22:16:15

标签: c# generics interface

我不确定我想要做什么甚至是一个好主意,但无论如何这里是问题:我有MyClass我希望实现两种不同类型的通用IEnumerable课程,例如

public class MyClass : IEnumerable<KeyValuePair<string, string>>,
                       IEnumerable<KeyValuePair<MyEnum, string>>

现在,这样做的问题是当我尝试从接口定义必要的方法时,编译器抱怨“Type'MyClass'已经定义了一个名为'GetEnumerator'且具有相同参数类型的成员”。这是因为我有这两种方法:

public IEnumerator<KeyValuePair<MyEnum, string>> GetEnumerator() { ... }
public IEnumerator<KeyValuePair<string, string>> GetEnumerator() { ... }

由于接口,我必须让GetEnumerator()没有参数,唯一不同的是返回类型,这是不允许的。

以下是我的选择:

  1. 我正在考虑拥有一个{main} IEnumerable泛型类型MyClass将实现,然后只添加因参数而不仅仅返回类型而不同的额外方法(例如Add) ,没有实现额外的通用接口。
  2. 我可以为MyClass创建一个通用基类,称之为MyBaseClass<T>,它会实现IEnumerable<KeyValuePair<T, string>>。然后,我会有不同版本的MyClass,例如MyClass<string>MyClass<MyEnum>
  3. 这在哪里似乎更合适,或者我错过了一些更好的解决方案?

4 个答案:

答案 0 :(得分:14)

您可以使用显式接口声明,以便为您实现的两个接口中的每一个获取不同的实现。例如:

public class MyClass : IEnumerable<KeyValuePair<string, string>>,
                   IEnumerable<KeyValuePair<MyEnum, string>>
{
    IEnumerator<KeyValuePair<MyEnum, string>> IEnumerable<KeyValuePair<MyEnum, string>>.GetEnumerator()
    {
        // return your enumerator here
    }

    IEnumerator<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator()
    {
        // return your enumerator here
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
        var me = this as IEnumerable<KeyValuePair<string, string>>;
        return me.GetEnumerator();
    }
}

然而,因为IEnumerable&lt;&gt;从IEnumerable派生,你必须从IEnumerable.GetEnumerator()调用中选择你想要返回的那个。

答案 1 :(得分:2)

你可以像这样明确地实现每个接口:

IEnumerable<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator() { ... }
IEnumerator<KeyValuePair<MyEnum, string>> IEnumerator<KeyValuePair<MyEnum, string>>.GetEnumerator() { ... }

答案 2 :(得分:2)

您可以使用explicit interface implementation来实现具有冲突方法的接口。但是,如果您实现了两个IEnumerable<T>接口,那么对于诸如foreach循环之类的东西,它会引起一些相当烦人的问题。我曾经尝试过这个,并立即回到实现1 IEnumerable接口,并提供另一个作为对象的属性。

答案 3 :(得分:0)

一种选择是实施interfaces explicitly

下行 - 你总是需要施放MyClass。