2010-11-22 64 views
1

这是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); 

你有什么建议?

回答

3

可以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 
} 
+0

抽象方法和属性都给出了相同的效果,即“必须实现它” – TalentTuner 2010-11-22 09:37:41

+0

嗨Nagg,这是诀窍。谢谢。 @saurabh:true,但这会强制Derived执行某些操作并实际返回列表(即使为空)。 – sh0uzama 2010-11-22 10:13:14

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

已经做到了这一点,它可能是适当改变FillMyListprivate,根据您的要求。另请注意,Derived中的方法必须标记为override

当然有许多不同的方法可以实现这一点。例如,您可以简单地使MyList属性本身为抽象,如Nagg所建议的。

+0

谢谢你,你的回答也非常有趣:) – sh0uzama 2010-11-22 10:14:22

0

我认为,如果事情是错误的(即列表中没有正确填写),那么你应该什么时候抛出一个异常正在尝试使用它。这样你总能得到正确的数据。即使这个类是抽象的,用户也可以将它实现为一个空方法,所以这并不好。

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。