Frage

Ich habe einige Arten, die von vereinfachten Base ableiten, wie unten dargestellt.

Ich bin nicht sicher, ob Basisklasse Konstruktor oder this Konstruktor zu verwenden, wenn Konstrukteure zu überlasten.

ConcreteA Überlastungen Konstrukteuren rein mit base Bauer, während
ConcreteB Überlastungen mit this für die ersten beiden Überlastungen.

Was wäre ein besserer Weg, Konstrukteure von Überlastung?

public abstract class Base
{
    public string Name { get; set; }
    public int? Age { get; set; }

    protected Base() : this(string.Empty) {}
    protected Base(string name) : this(name, null) {}
    protected Base(string name, int? age)
    {
        Name = name;
        Age = age;
    }
}

public class ConcreteA : Base
{
    public ConcreteA(){}
    public ConcreteA(string name) : base(name) {}
    public ConcreteA(string name, int? age) : base(name, age)
    {
    }
}

public class ConcreteB : Base
{
    public ConcreteB() : this(string.Empty, null){}
    public ConcreteB(string name): this(name, null){}
    public ConcreteB(string name, int? age) : base(name, age)
    {
    }
}

[Bearbeiten] Es sieht aus wie das, was Ian Quigley in seiner Antwort vorgeschlagen schien Sinn machen. Wenn ich einen Anruf haben war, der Validatoren initialisieren, ConcreteA(string) nie Validatoren initialisieren, falls folgen.

public class ConcreteA : Base
{
    public ConcreteA(){}
    public ConcreteA(string name) : base(name) {}
    public ConcreteA(string name, int? age) : base(name, age)
    {
        InitializeValidators();
    }
    private void InitializeValidators() {}
}
War es hilfreich?

Lösung

Das . Denn wenn Sie jemals Code in ConcreteB platzieren (string, int?), Dann wollen Sie die Zeichenfolge nur Konstruktor es zu nennen.

Andere Tipps

Im Allgemeinen würde ich „diese“ und nicht als „Basis“ nennen. Sie werden wahrscheinlich mehr Code auf diese Weise wiederverwenden, wenn Sie später auf Ihre Klassen erweitern.

Es ist gut zu mischen und anzupassen; schließlich, wenn Sie einen this(...) Konstruktor verwenden, wird es schließlich zu einem Ctor erhalten, die base(...) ruft zuerst. Es macht Sinn, wieder zu verwenden Logik, wo erforderlich.

Sie können es so einrichten, dass alle Konstrukteure eine gemeinsame (vielleicht privat) this(...) Konstruktor aufgerufen, die die einzige ist, die auf die base(...) ruft nach unten - aber das hängt davon ab, ob ein: es ist sinnvoll, so zu tun, und b: ob es ein einziges base(...) ctor ist, dass Sie lassen würde.

In Ihrem Fall von dem, was Sie zur Verfügung gestellt haben, es spielt keine Rolle. Sie wirklich nur this verwenden möchten, wenn Sie einen Konstruktor in der aktuellen Klasse, die nicht Teil Ihrer Basisklasse ist, oder wenn es einige Code in der aktuellen Klasse Konstruktor, dass Sie das ausführen möchten, nicht in der Basisklasse enthalten .

Um die Komplexität der Codepfade zu reduzieren, versuche ich in der Regel genau ein base() Konstruktoraufruf zu haben (die ConcreteB Fall). Auf diese Weise wissen Sie, dass die Initialisierung der Basisklasse geschieht immer in der gleichen Art und Weise.

Allerdings, je Sie von der Klasse außer Kraft setzen, kann dies nicht möglich sein oder nicht benötigte Komplexität hinzuzufügen. Dies gilt für spezielle Konstruktor Muster wie das bei ISerializable .

Stellen Sie sich wieder, warum Sie den Konstruktor in der Basisklasse zu überlasten? Dies ist genug:

protected Base()

Das Gleiche gilt für die Unterklasse geht, wenn Sie entweder Felder benötigen einen bestimmten Wert zu haben, wenn Sie die in Ihrem Beispiel instanziiert ist nicht der Fall, da Sie bereits die Default-Konstruktor haben.

Denken Sie auch daran, dass jeder Konstrukteur die Instanz des Objekts in einem korrekten Zustand versetzt soll.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top