代码之家  ›  专栏  ›  技术社区  ›  Sarah Vessels

实现两个不同的通用接口

  •  2
  • Sarah Vessels  · 技术社区  · 16 年前

    我不确定我想做什么甚至是个好主意,但问题是:我有 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. 我在考虑有一个“主要” 可枚举的 泛型类型 类名 将实现,然后只添加参数不同的额外方法,而不仅仅是返回类型(例如 Add ,而不实现额外的通用接口。
    2. 我可以为 类名 称之为 MyBaseClass<T> 它将实现 IEnumerable<KeyValuePair<T, string>> . 那么,我会有不同版本的 类名 ,例如 MyClass<string> MyClass<MyEnum> .

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

    4 回复  |  直到 16 年前
        1
  •  14
  •   scwagner    16 年前

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

    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<gt;是从IEnumerable派生的,因此必须从IEnumerable.GetEnumerator()调用中选择要返回的类型。

        2
  •  2
  •   Sam Harwell    16 年前

    你可以使用 explicit interface implementation 用相互冲突的方法实现接口。但是,如果您实现两个 IEnumerable<T> 接口,它会导致一些相当烦人的问题,比如 foreach 循环。我曾经尝试过这种方法,并立即返回到实现1 IEnumerable 接口,并将另一个作为对象的属性提供。

        3
  •  2
  •   Charlie Gevious    16 年前

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

    IEnumerable<KeyValuePair<string, string>> IEnumerable<KeyValuePair<string, string>>.GetEnumerator() { ... }
    IEnumerator<KeyValuePair<MyEnum, string>> IEnumerator<KeyValuePair<MyEnum, string>>.GetEnumerator() { ... }
    
        4
  •  0
  •   Arnis Lapsa    16 年前

    一个选择是实施 interfaces explicitly .

    缺点-你总是需要铸造我的类。