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.
精彩评论