Как заставить производный класс заполнить список, определенный в базовом классе? - PullRequest
1 голос
/ 22 ноября 2010

Это связано с C #, но на самом деле вопрос довольно общий.

Допустим, у меня есть базовый класс

abstract class Base {
    protected List<string> MyList = new List<string>();
    protected abstract void FillMyList();
}

class Derived : Base {
    protected void FillMyList() {
        MyList.Add("test");
        MyList.Add("test2");
    }
}

Это нормально, производный класс заполняет MyList, определенный в базовом классе.

Однако, кроме абстрактного имени метода (FillMyList) - которое намекает на то, что вы на самом деле ДОЛЖНЫ заполнять MyList - нет никакой подсказки о том, что этот метод должен означать.

Есть ли лучший способ обеспечить или (лучше) настоятельно рекомендовать, чтобы вам приходилось заполнять MyList при наследовании от Base? Может быть, FillMyList объявлен как:

protected abstract void FillMyList(List<string> listToFill);

Что вы предлагаете?

Ответы [ 4 ]

3 голосов
/ 22 ноября 2010

Вы можете преобразовать MyList в абстрактное свойство с помощью getter, который должен реализовывать

.
public abstract class Base
{
    public abstract List<int> List { get; }
}

public class Derived : Base
{
    #region Overrides of Base

    public override List<int> List
    {
        get { return new List<int> {1, 2, 3}; }
    }

    #endregion
}
1 голос
/ 22 ноября 2010

Вы можете сделать что-то подобное:

abstract class Base {
     protected List<string> TheList
     {
         get {
             Debug.Assert(MyList.Count != 0);
             return MyList;
         }
         set {
             Debug.Assert(value.Count != 0);
             MyList = value;
         }
     }
     private List<string> MyList = new List<string>();
}

ваш производный может получить доступ к MyList только через свойство, которое будет выполнять проверку.

1 голос
/ 22 ноября 2010

Как вы определяете «заполнить»?Если вы просто имеете в виду «добавить некоторые элементы», то вы можете просто добавить другой абстрактный метод для извлечения элементов, которые нужно добавить, а затем реализовать FillMyList в базовом классе, чтобы добавить их в список.Например:

abstract class Base
{
    protected List<string> MyList = new List<string>();

    protected abstract IEnumerable<string> GetItems();

    protected void FillMyList()
    {
        MyList.AddRange(GetItems());
    }
}

class Derived : Base
{
    protected override IEnumerable<string> GetItems()
    {
        yield return "test";
        yield return "test2";
    }
}

После этого может быть целесообразно изменить FillMyList на private, в зависимости от ваших требований.Также обратите внимание, что метод в Derived должен быть помечен как override.

Конечно, есть много разных способов достижения этого.Вы можете просто сделать собственное свойство MyList абстрактным, например, как предложено Наггом.

0 голосов
/ 22 ноября 2010

Я думаю, что если что-то не так (т. Е. Список не заполнен должным образом), вы должны выдать исключение, когда пытаетесь его использовать.Таким образом, вы всегда будете получать правильные данные.Даже если класс абстрактный, пользователь может реализовать его как пустой метод, так что это не намного лучше.

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