Абстрактный базовый класс, который наследует ICollection <T> - PullRequest
6 голосов
/ 28 июля 2011

Предположим, у меня есть абстрактный базовый класс BaseTimeCollection и хотя бы один конкретный класс ConcreteTimeCollection, который наследуется от базового класса.

Я бы хотел, чтобы мой базовый класс наследовал от ICollection<T>.

Наследование от ICollection<T> требует от меня предоставления реализаций для ряда методов, включая IEnumerable.GetEnumerator() и IEnumerable<T>.GetEnumerator.

Я не хочу реализовывать эти методы в BaseTimeCollection - вместо этого я бы предпочел реализовать их индивидуально в каждом из моих конкретных классов.

Здесь я сталкиваюсь с неприятностями.

Методы GetEnumerator должны быть объявлены явно, потому что есть два из них, оба с одинаковым именем, но с разными типами возврата. Однако, похоже, что как только я сделаю подпись явной, я больше не могу использовать абстрактный модификатор. По сути, я вынужден реализовать метод 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 ]

6 голосов
/ 28 июля 2011

Вы можете легко отложить реализацию до своих дочерних классов, если явные реализации вызовут защищенные абстрактные методы в вашем абстрактном классе, а затем позволят детям реализовать эти абстрактные методы:

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

Извините за плохое именованиесхема ... это лучшее, что я мог придумать этим рано утром.

0 голосов
/ 26 марта 2013

Нет необходимости реализовывать обе версии 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) ...
}
0 голосов
/ 28 июля 2011

Прежде всего: Какую ошибку компиляции вы получаете?

Вам нужен базовый класс, возможно, вы можете просто использовать другой интерфейс, например:

public interface BaseTimeCollection : ICollection<Time> {}

, и затем ваши реализации реализуют этот интерфейс вместо вашего базового класса, или у вас есть какой-тообщая функциональность?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...