如何强制派生类填充基类中定义的列表?

时间:2010-11-22 09:28:10

标签: c# polymorphism

这与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 - 没有任何关于这个方法意味着什么的线索。

有没有更好的方法来强制执行或(更好)强烈建议您在继承Base时必须填写MyList? 也许将FillMyList声明为:

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

你有什么建议?

4 个答案:

答案 0 :(得分:3)

您可以使用getter将MyList转换为abstract属性,派生必须实现

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 :(得分:1)

如何定义“填充”?如果你的意思是“添加一些元素”,那么你可以简单地添加另一个抽象方法来检索要添加的项,然后在基类中实现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属性本身设为抽象,例如,如Nagg所建议的那样。

答案 2 :(得分:1)

你可以这样做:

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。

答案 3 :(得分:0)

我认为如果出现问题(即列表未正确填充),那么在尝试使用它时应该抛出异常。这样您就可以获得正确的数据。即使类是抽象的,用户也可以将它作为一个空方法实现,所以这不是更好。