【问题标题】:C# implement two different generic interfacesC# 实现两个不同的泛型接口
【发布时间】:2009-08-11 22:16:15
【问题描述】:

我不确定我想要做什么甚至是一个好主意,但问题仍然存在:我有MyClass,我想实现两种不同类型的通用IEnumerable 类,例如

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

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

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

我必须有GetEnumerator()因为接口的原因不带参数,唯一不同的是返回类型,这是不允许的。

以下是我的选择:

  1. 我正在考虑使用 MyClass 将实现的“主要”IEnumerable 泛型类型,然后仅添加因参数而异的额外方法,而不仅仅是返回类型(例如 Add),而不实现额外的泛型接口。
  2. 我可以为MyClass 创建一个通用基类,将其命名为MyBaseClass&lt;T&gt;,它将实现IEnumerable&lt;KeyValuePair&lt;T, string&gt;&gt;。然后,我会有不同版本的MyClass,例如MyClass&lt;string&gt;MyClass&lt;MyEnum&gt;

这里似乎更可取,还是我错过了一些更好的解决方案?

【问题讨论】:

标签: c# generics interface


【解决方案1】:

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

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 派生自 IEnumerable,因此您必须从 IEnumerable.GetEnumerator() 调用中选择要返回的值。

【讨论】:

    【解决方案2】:

    您可以使用explicit interface implementation 来实现具有冲突方法的接口。然而,如果你实现了两个IEnumerable&lt;T&gt; 接口,它会为foreach 循环之类的事情带来一些相当烦人的问题。我曾经尝试过这样做,然后立即返回实现 1 IEnumerable 接口,并将另一个作为对象的属性提供。

    【讨论】:

    • 2 分钟内关于显式接口的 5 个答案。 :D
    • 是的,但只有我的提供了改进的解决方案 :deal: :)
    • 我不会参加“谁会更好地改进他的答案”比赛。 :)
    【解决方案3】:

    您可以像这样显式地实现每个接口:

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

    【讨论】:

      【解决方案4】:

      一种选择是实现interfaces explicitly

      缺点 - 你总是需要转换 MyClass。

      【讨论】:

        猜你喜欢
        • 2023-04-04
        • 1970-01-01
        • 2017-02-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-17
        相关资源
        最近更新 更多