继承ICollection<T>的抽象基类。

6
假设我有一个抽象基类BaseTimeCollection和至少一个从该基类继承的具体类ConcreteTimeCollection。
我希望我的基类可以从ICollection继承。
从ICollection继承需要我提供一些方法的实现,包括IEnumerable.GetEnumerator()和IEnumerable.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 方法的实现推迟到具体的类中?


你遇到了哪个编译错误? - Tomas Jansson
3个回答

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();
    }
}

抱歉命名方案不太好……这是我早上想到的最好方案。


看起来应该可以解决问题了 - 谢谢!回想起来似乎很明显 :) - knick
1
不需要有两个抽象实现,因为非泛型实现可以调用泛型抽象方法。 - supercat

0
首先:您遇到了什么编译错误?
您是否需要您的基类?也许您可以使用另一个接口,例如:
public interface BaseTimeCollection : ICollection<Time> {}

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


对于我在帖子中提供的示例代码,我得到的编译错误是“修饰符'abstract'对此项无效”。这个错误指向基类中的两个抽象方法声明。是的,我确实有一些通用功能没有包含在示例中。 - knick

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) ...
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接