继承ICollection <t> </t>的抽象基类

时间:2011-07-28 13:47:58

标签: c# inheritance collections interface

假设我有一个抽象基类BaseTimeCollection和至少一个继承自基类的具体类ConcreteTimeCollection

我希望我的基类继承自ICollection<T>

继承ICollection<T>要求我提供多种方法的实施,包括IEnumerable.GetEnumerator()IEnumerable<T>.GetEnumerator

我不想在BaseTimeCollection中实现这些方法 - 相反,我更愿意在每个具体类中单独实现它们。

这是我遇到麻烦的地方。

GetEnumerator方法需要明确声明,因为它们中有两个具有相同的名称但返回类型不同。 但是,似乎只要我使签名显式,我就不能再使用abstract修饰符了。基本上我被迫在我的基类中实现GetEnumerator方法。

public abstract class BaseTimeCollection : ICollection<Time>
{
    abstract IEnumerator IEnumerable.GetEnumerator();  // compile error: The modifier    'abstract' is not valid for this item
    abstract IEnumerator<Time> IEnumerable<Time>.GetEnumerator(); // compile error: The       modifier 'abstract' is not valid for this item
}

public class ConcreteTimeCollection : BaseTimeCollection
{
    IEnumerator IEnumerable.GetEnumerator()
    {
       // this is where I would like to provide my implementation for IEnumerable.GetEnumerator()
    }

    IEnumerator<Time> IEnumerable<Time>.GetEnumerator()
    {
        // this is where I would like to provide my implementation for IEnumerable<Time>.GetEnumerator()
    }
}
  1. 我错过了什么?

  2. 我是否可以通过某种方式将GetEnumerator方法的实现推迟到具体类中?

3 个答案:

答案 0 :(得分:6)

通过让显式实现在抽象类中调用受保护的抽象方法,然后让子级实现这些抽象方法,您可以轻松地将实现推迟到子类:

public abstract class BaseTimeCollection : ICollection<Time>
{
    protected abstract IEnumerator IEnumerable_GetEnumerator();
    protected abstract IEnumerator<Time> GenericEnumerable_GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() 
    { 
        return IEnumerable_GetEnumerator(); 
    }

    IEnumerator<Time> IEnumerable<Time>.GetEnumerator()
    {
        return GenericEnumerable_GetEnumerator();
    }
}

对于糟糕的命名方案感到抱歉......这是我早上能想到的最好的。

答案 1 :(得分:0)

首先:你得到的编译错误是什么?

你需要你的基类,也许你可以使用另一个界面,如:

public interface BaseTimeCollection : ICollection<Time> {}

然后让你的实现实现该接口而不是你的基类,或者你有一些共同的功能吗?

答案 2 :(得分:0)

没有必要显式地实现两个版本的GetEnumerator来防止名称冲突,所以除非另外要求它们都是显式的,否则你可以使泛型方法隐式,这样它也可以是抽象的。然后,根据@supercat,非泛型方法可以调用泛型方法。

public abstract class BaseTimeCollection<Time> : ICollection<Time>
{
    public abstract IEnumerator<Time> GetEnumerator(); // implicit, generic and abstract

    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    // Other ICollection methods (Add, Clear, etc) ...
}