简体   繁体   English

继承ICollection <T>的抽象基类

[英]Abstract base class that inherits ICollection<T>

Suppose I have an abstract base class BaseTimeCollection and at least one concrete class ConcreteTimeCollection which inherits from the base class. 假设我有一个抽象基类BaseTimeCollection和至少一个BaseTimeCollection类的具体类ConcreteTimeCollection

I would like my base class to inherit from ICollection<T> . 我希望我的基类继承ICollection<T>

Inheriting from ICollection<T> requires me to provide implementations for a number of methods, including IEnumerable.GetEnumerator() and IEnumerable<T>.GetEnumerator . 继承ICollection<T>需要我提供许多方法的实现,包括IEnumerable.GetEnumerator()IEnumerable<T>.GetEnumerator

I do not want to implement these methods in BaseTimeCollection - instead I would prefer to implement them individually in each of my concrete classes. 我不想在BaseTimeCollection实现这些方法 - 相反,我更愿意在每个具体类中单独实现它们。

This is where I run into trouble. 这是我遇到麻烦的地方。

The GetEnumerator methods need to be declared explicitly, because there are two of them both with the same name but different return types. 需要显式声明GetEnumerator方法,因为它们中的两个具有相同的名称但返回类型不同。 However, it seems that as soon as I make the signature explicit I can no longer use the abstract modifier. 但是,似乎只要我使签名显式,我就不能再使用abstract修饰符了。 Essentially I am forced to implement the GetEnumerator method in my base class. 基本上我被迫在我的基类中实现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. What have I missed? 我错过了什么?

  2. Is there some way I can defer implementation of the GetEnumerator methods to the concrete classes? 有没有什么方法可以将GetEnumerator方法的实现推迟到具体类?

You can easily defer the implementation to your child classes by having the explicit implementations call protected abstract methods in your abstract class and then letting the children implement those abstract methods: 通过让显式实现在抽象类中调用受保护的抽象方法,然后让子级实现这些抽象方法,您可以轻松地将实现推迟到子类:

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

Sorry for the poor naming scheme...it's the best I could come up with this early in the morning. 抱歉这个糟糕的命名方案......这是我早上最好能想到的。

It's not necessary to implement both versions of GetEnumerator explicitly to prevent the name clash, so unless there's another requirement for them both to be explicit, you could make the generic method implicit so that it can also be abstract. 没有必要显式地实现两个版本的GetEnumerator来防止名称冲突,所以除非另外要求它们都是显式的,否则你可以使泛型方法隐式,这样它也可以是抽象的。 Then, as per @supercat, the non-generic method can call the generic one. 然后,根据@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) ...
}

First of all: What is the compile error you are getting? 首先:你得到的编译错误是什么?

Do you need your base class, maybe you can just use another interface like: 你需要你的基类,也许你可以使用另一个界面,如:

public interface BaseTimeCollection : ICollection<Time> {}

and then have your implementations implement that interface instead of your base class, or do you have some common functionality? 然后让你的实现实现该接口而不是你的基类,或者你有一些共同的功能?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM