2010-11-22 6 views
1

Ceci est lié à C#, mais en fait la question est assez générique.Comment forcer une classe dérivée à remplir une liste définie dans la classe de base?

Disons que j'ai une classe de base

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

Ceci est ok, la classe dérivée remplit la MyList définie dans la classe de base. Cependant, en plus du nom de la méthode abstraite (FillMyList) - qui indique que vous devez réellement remplir MyList - il n'y a aucune idée de ce que cette méthode est censée signifier.

Existe-t-il une meilleure façon d'appliquer ou (mieux) de suggérer fortement que vous devrez remplir MyList lorsque vous héritez de Base? Peut-être avoir le FillMyList déclaré:

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

Que proposez-vous?

Répondre

3

Vous pouvez convertir MyList à la propriété abstraite avec getter, qui dérivé doit mettre en œuvre

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

La méthode abstraite et la propriété donnent tous les deux le même effet, c'est-à-dire "doit l'implémenter" – TalentTuner

+0

Salut Nagg, ça fait l'affaire. Merci. @saurabh: true, mais cela oblige le Dérivé à faire quelque chose et à retourner la liste (même vide). – sh0uzama

1

Comment définir "remplissage"? Si vous voulez juste dire "ajouter quelques éléments", vous pouvez simplement ajouter une autre méthode abstraite pour récupérer les éléments à ajouter, puis implémenter FillMyList dans la classe de base pour les ajouter à la liste. Par exemple:

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

Après avoir fait cela, il peut être approprié de changer FillMyList-private, en fonction de vos besoins. Notez également que la méthode au Derived doit être marquée comme override.

Bien entendu, il existe de nombreuses façons d'y parvenir. Vous pourriez simplement rendre la propriété MyList elle-même abstraite, par exemple, comme suggéré par Nagg.

+0

Merci Will, votre réponse est aussi très intéressante :) – sh0uzama

0

Je pense que si quelque chose ne va pas (ie. La liste n'est pas rempli correctement), alors vous devriez jeter une exception lorsque vous essayons de l'utiliser. De cette façon, vous aurez toujours les bonnes données. Même si la classe est abstraite, l'utilisateur peut l'implémenter comme une méthode vide, ce n'est donc pas beaucoup mieux.

1

Vous pouvez faire quelque chose comme ça:

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

votre dérivée peut accéder à MyList que par la propriété qui fera le chèque.

Questions connexes