2009-04-15 7 views
7

J'ai quelques types qui découlent de Base simplifiée comme indiqué ci-dessous.Surcharge "base" constructeur ou "this" constructeur?

Je ne suis pas sûr d'utiliser le constructeur de la classe de base ou le constructeur this lors de la surcharge des constructeurs.

ConcreteA surcharges constructeurs utilisant purement base constructeurs, tout en
thisConcreteB surcharges en utilisant pour les deux premières surcharges.

Quelle serait une meilleure façon de surcharger les constructeurs?

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

[Modifier] Il ressemble à ce que Ian Quigley a suggéré dans son answer semblait logique. Si je devais avoir un appel qui initialise les validateurs, ConcreteA(string) n'initialisera jamais les validateurs dans le cas suivant.

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

Répondre

5

Cette. Car si vous placez du code dans ConcreteB (string, int?), Alors vous voulez que le constructeur de la chaîne seule l'appelle.

+0

Cela semble logique si je devais avoir d'autres initialisations en cours dans les constructeurs concrets. – Sung

+0

Oui, et "this" appellera toujours "base" à la fin de la journée. Donc, même si "ceci" ne fait rien, il va tomber à "baser" –

1

Dans votre cas, peu importe ce que vous avez fourni. Vous voulez seulement utiliser this quand vous avez un constructeur dans votre classe actuelle qui ne fait pas partie de votre classe de base, ou s'il y a du code dans le constructeur de classe actuel que vous voulez exécuter qui n'est pas contenu dans la classe de base .

2

En général, j'appellerais «ceci» plutôt que «base». Vous réutiliserez probablement plus de code de cette façon, si vous développez vos classes plus tard.

0

Afin de réduire la complexité des chemins de code, j'essaie généralement d'avoir exactement un appel de constructeur base() (le cas ConcreteB). De cette façon, vous savez que l'initialisation de la classe de base se produit toujours de la même manière. Toutefois, en fonction de la classe que vous remplacez, cela peut ne pas être possible ou ajouter une complexité inutile. Cela est vrai pour les modèles de constructeur spéciaux tels que celui utilisé lors de l'implémentation ISerializable.

2

Il est bon de mélanger et assortir; en fin de compte, lorsque vous utilisez un constructeur this(...), il va éventuellement arriver à un ctor qui appelle d'abord base(...). Il est logique de réutiliser la logique si nécessaire.

Vous pouvez l'organiser pour que tous les constructeurs appellent un constructeur commun (peut-être privé) this(...) qui est le seul qui appelle le base(...) - mais cela dépend si: il est utile de le faire, et b : s'il y a un seul base(...) ctor qui vous laisserait.

0

Demandez-vous à nouveau pourquoi vous surchargez le constructeur dans la classe de base? Celui-ci est assez:

protected Base() 

va de même pour la sous-classe, sauf si vous devez soit les champs d'avoir une valeur particulière lorsque vous instancier qui dans votre exemple est pas le cas puisque vous avez déjà le constructeur par défaut.

Rappelez-vous également que tout constructeur doit mettre l'instance de l'objet dans un état correct.