2009-04-15 10 views
7

Ich habe einige Typen, die von vereinfachten Base abgeleitet sind, wie unten gezeigt.Überladen Sie "Basis" -Konstruktor oder "dieser" Konstruktor?

Ich bin nicht sicher, ob der Konstruktor der Basisklasse oder der Konstruktor this beim Überladen von Konstruktoren verwendet werden soll.

ConcreteA Überlastungen Konstruktoren rein Verwendung base Konstruktoren, während
ConcreteB Überlastungen this für die ersten beiden Überlastungen verwendet.

Was wäre eine bessere Möglichkeit, Konstruktoren zu überlasten?

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 vorgeschlagen hat seine answer schien Sinn zu machen. Wenn ich einen Anruf habe, der Validatoren initialisiert, wird ConcreteA(string) niemals die Validatoren im folgenden Fall initialisieren.

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

Antwort

5

Diese. Weil, wenn Sie jemals Code in ConcreteB (string, int?) Platzieren, dann möchten Sie den Konstruktor nur für den String aufrufen.

+0

Dies scheint sinnvoll zu sein, wenn ich in konkreten Konstruktoren andere Initialisierungen durchführen würde. – Sung

+0

Ja, und "dies" wird immer "Basis" am Ende des Tages nennen. Selbst wenn "dies" nichts bewirkt, wird es auf "Basis" fallen. –

1

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

2

Im Allgemeinen würde ich "dieses" eher als "Basis" nennen. Sie werden wahrscheinlich mehr Code auf diese Weise wiederverwenden, wenn Sie Ihre Klassen später erweitern.

0

Um die Komplexität der Code Pfade zu reduzieren, versuche ich normalerweise genau einen base() Konstruktor Aufruf (der ConcreteB Fall). Auf diese Weise wissen Sie, dass die Initialisierung der Basisklasse immer auf die gleiche Weise erfolgt.

Abhängig von der Klasse, die Sie überschreiben, ist dies jedoch möglicherweise nicht möglich oder Sie fügen unnötige Komplexität hinzu. Dies gilt für spezielle Konstruktormuster wie dasjenige bei der Implementierung ISerializable.

2

Es ist in Ordnung zu mischen und zusammenzupassen; Schließlich, wenn Sie einen this(...) Konstruktor verwenden, wird es schließlich zu einem Ctor, der zuerst base(...) ruft. Es ist sinnvoll, die Logik wo erforderlich wiederzuverwenden.

Man könnte 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 sinnvoll ist, dies zu tun, und b : ob es eine einzige base(...) ctor gibt, die Sie lassen würde.

0

Fragen Sie sich noch einmal, warum Sie den Konstruktor in der Basisklasse überladen? Dieses 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 in Ihrem Beispiel instanziiert das ist nicht der Fall, da Sie bereits den Standard-Konstruktor haben.

Denken Sie auch daran, dass jeder Konstruktor die Instanz des Objekts in einen korrekten Zustand versetzen sollte.

Verwandte Themen