2010-11-22 13 views
1

Dies ist C# verwandt, aber eigentlich ist die Frage ziemlich generisch.Wie erzwinge eine abgeleitete Klasse, um eine in der Basisklasse definierte Liste zu füllen?

Nehmen wir an, ich habe eine Basisklasse

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

Das ist in Ordnung, die abgeleitete Klasse die MyList in der Basisklasse definiert füllt.

Neben dem Namen der abstrakten Methode (FillMyList) - der darauf hinweist, dass Sie tatsächlich MyList füllen müssen - gibt es keine Hinweise darauf, was diese Methode bedeuten soll.

Gibt es eine bessere Möglichkeit zu erzwingen oder (besser) stark darauf hinzuweisen, dass Sie MyList füllen müssen, wenn Sie von Base erben? Vielleicht ist der FillMyList mit erklärt wie:

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

Was schlagen Sie vor?

Antwort

3

Sie können MyList auf abstrakte Eigenschaft mit Getter wandeln, die Umsetzung abgeleitet müssen

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

Abstrakte Methode und Eigenschaft beide gibt den gleichen Effekt, d. H. "Hat es zu implementieren" – TalentTuner

+0

Hallo Nagg, das macht den Trick. Vielen Dank. @saurabh: true, aber dies zwingt das Abgeleitete etwas zu tun und gibt die Liste tatsächlich zurück (selbst wenn es leer ist). – sh0uzama

1

Wie definieren Sie "füllen"? Wenn Sie nur "Hinzufügen einiger Elemente" meinen, können Sie einfach eine weitere abstrakte Methode hinzufügen, um die hinzuzufügenden Elemente abzurufen, und dann FillMyList in der Basisklasse implementieren, um diese zur Liste hinzuzufügen. Zum Beispiel:

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

dies getan haben, kann es sinnvoll sein FillMyList-private zu ändern, je nach Ihren Anforderungen. Beachten Sie auch, dass die Methode in Derived als override gekennzeichnet werden muss.

Es gibt natürlich viele verschiedene Möglichkeiten, dies zu erreichen. Sie könnten einfach die MyList Eigenschaft selbst abstrakt machen, zum Beispiel wie von Nagg vorgeschlagen.

+0

Vielen Dank Will, Ihre Antwort ist auch sehr interessant :) – sh0uzama

0

Ich denke, dass, wenn etwas nicht in Ordnung ist (dh. Die Liste nicht richtig gefüllt ist), dann sollten Sie eine Ausnahme auslösen, wenn Sie versuchen es zu benutzen. Auf diese Weise erhalten Sie immer die richtigen Daten. Selbst wenn die Klasse abstrakt ist, kann der Benutzer sie als eine leere Methode implementieren, so dass dies nicht viel besser ist.

1

Sie so etwas tun könnte:

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

abgeleiteten MyList nur durch die Eigenschaft zugreifen können, die den Scheck tun.

Verwandte Themen