开发者

How to force a derived class to fill a list defined in the base class?

This is C# related, but actually the question is quite generic.

Let's say that I have a base class

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

class Derived :开发者_如何学C Base {
    protected void FillMyList() {
        MyList.Add("test");
        MyList.Add("test2");
    }
}

This is ok, the derived class fills the MyList defined in the base class.

However, besides the abstract method name (FillMyList) - that hints that you actually HAVE to fill MyList - there is no clue to what this method is supposed to mean.

Is there a better way to enforce or (better) suggest strongly that you will have to fill MyList when you are inheriting from Base? Maybe having the FillMyList declared as:

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

What do you suggest?


You can convert MyList to abstract property with getter, which derived must implementing

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
}


You could do something like that:

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

your derived can access MyList only through the property that will do the check.


How do you define "fill"? If you just mean "add some elements", then you could simply add another abstract method to retrieve the items to be added, then implement FillMyList in the base class to add these to the list. For example:

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";
    }
}

Having done this, it may be appropriate to change FillMyList to private, depending on your requirements. Also note that the method in Derived must be marked as override.

There are many different ways of achieving this, of course. You could simply make the MyList property itself abstract, for example, as suggested by Nagg.


I think that if something is wrong (ie. the list is not filled properly) then you should throw an exception when you are trying to use it. This way you'll always get the proper data. Even if the class is abstract the user can implement it as an empty method so this is not much better.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜