[英]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()
}
}
What have I missed? 我错过了什么?
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.