78 votes

Meilleures pratiques pour les constructeurs base() et this()

Dans quelles conditions suis-je censé faire le :base() y :this() à la suite des parenthèses de mon constructeur (ou même à d'autres endroits du code). Quand ces appels sont-ils une bonne pratique et quand sont-ils obligatoires ?

99voto

Mark Byers Points 318575

: base(...)

Si vous omettez l'appel à un constructeur de base, il appellera automatiquement le constructeur de base par défaut.

Il est obligatoire d'appeler explicitement un constructeur de base s'il n'existe pas de constructeur par défaut.

Même s'il existe un constructeur par défaut, vous pouvez toujours souhaiter appeler un constructeur différent de celui par défaut. Dans ce cas, vous pouvez toujours utiliser base(foo, bar) pour appeler un constructeur différent du constructeur de base.

Je ne considère pas que ce soit une mauvaise pratique d'omettre base() lorsque vous voulez faire appel au constructeur par défaut de la classe de base, bien que si vous aimez être explicite, je ne vois aucun mal à l'inclure. C'est une question de goût.

: this(...)

Cette syntaxe vous permet d'appeler un constructeur avec une signature différente d'un autre au sein de la même classe. Il n'est jamais obligatoire de le faire, mais cela peut parfois être utile.

Un exemple de cas où cela peut être utile est la réutilisation de code commun dans les constructeurs. Par exemple, en C# 3.5 ou avant, vous pouvez vouloir simuler des paramètres optionnels sur un constructeur :

Foo(int x, int y)
{
     this.x = x;
     this.y = y;
}

Foo(int x) : this(x, 10) {}  // y defaults to 10

Avec C# 4.0, les paramètres facultatifs sont désormais disponibles, ce qui réduit la nécessité de cette approche.

Une autre façon de réutiliser le code dans les constructeurs est de le factoriser dans une fonction statique qui est appelée par chaque constructeur qui souhaite l'utiliser.

35voto

configurator Points 15594

Tout d'abord, quand ils sont obligatoires.

Lorsqu'une classe Derived est dérivé d'une classe Base y Base n'a pas de constructeur par défaut (sans paramètre), Derived doit appeler base() explicitement avec des paramètres.

public class Base {
    public Base(int i) { }
}

public class Derived : Base {
    // public Derived() { } wouldn't work - what should be given for i?
    public Derived() : base(7) { }
    public Derived(int i) : base(i) { }
}

Quand est-ce une bonne pratique ? Chaque fois que vous voulez appeler un constructeur différent.

Supposons que vous ajoutez, dans mon exemple précédent, du contenu aux constructeurs dans Derived.

public class Derived : Base {
    // public Derived() { } wouldn't work - what should be given for i?
    public Derived() : base(7) {
        Console.WriteLine("The value is " + 7);
    }
    public Derived(int i) : base(i) {
        Console.WriteLine("The value is " + i);
    }
}

Vous avez remarqué la duplication ici ? Il est plus simple d'appeler le constructeur this().

public class Derived : Base {
    // public Derived() { } wouldn't work - what should be given for i?
    public Derived() : this(7) { }
    public Derived(int i) : base(i) {
        Console.WriteLine("The value is " + i);
    }
}

32voto

ANaimi Points 1396

Utilice base lorsqu'il existe un héritage et qu'une classe parente fournit déjà la fonctionnalité que vous essayez d'obtenir.

Utilice this lorsque vous voulez référencer l'entité courante (ou self), utilisez-le dans l'en-tête/signature du constructeur lorsque vous ne voulez pas dupliquer une fonctionnalité qui est déjà définie dans un autre constructeur.

En gros, en utilisant base et this dans l'en-tête d'un constructeur est de garder votre code SEC ce qui le rend plus facile à maintenir et moins verbeux.

Voici un exemple absolument dénué de sens, mais je pense qu'il illustre l'idée de montrer comment les deux peuvent être utilisés.

class Person
{
    public Person(string name)
    {
        Debug.WriteLine("My name is " + name);
    }
}

class Employee : Person
{
    public Employee(string name, string job)
        : base(name)
    {
        Debug.WriteLine("I " + job + " for money.");
    }

    public Employee() : this("Jeff", "write code")
    {
        Debug.WriteLine("I like cake.");
    }
}

Utilisation :

var foo = new Person("ANaimi");
// output:
//  My name is ANaimi

var bar = new Employee("ANaimi", "cook food");
// output:
//  My name is ANaimi
//  I cook food for money.

var baz = new Employee();
// output:
//  My name is Jeff
//  I write code for money.
//  I like cake.

8voto

alxx Points 9064

Cherchez "constructor chaining in C#". En gros, ça ressemble à ça :

MyClass():base()  //default constructor calling superclass constructor
{
}

MyClass(int arg):this()  //non-basic constructor calling base constructor
{
    //extra initialization
}

Il permet de supprimer la duplication de code dans les constructeurs - les diviser en parties basiques et spécifiques.

4voto

Andrea Parodi Points 2618

Vous utilisez :base() lorsque vous voulez que le constructeur de la classe de base soit automatiquement appelé comme première instruction de votre constructeur. :this() est similaire, mais il appelle un autre constructeur sur la même classe.

Dans base :() et this() : vous pouvez passer comme paramètres des valeurs constantes, ou des expressions basées sur les paramètres de votre constructeur.

Il est obligatoire d'appeler le constructeur de base lorsque la classe de base n'a pas de constructeur par défaut (qui ne prend pas de paramètres). Je ne connais pas de cas dans lequel :this() est obligatoire.

public class ABaseClass
{
    public ABaseClass(string s) {}
}

public class Foo : AChildClass
{
    public AChildClass(string s) : base(s) {} //base mandatory
    public AChildClass() : base("default value") {}  //base mandatory
    public AChildClass(string s,int i) : base(s+i) {}  //base mandatory
}

public class AnotherBaseClass
{
    public ABaseClass(string s) {}
    public ABaseClass():this("default value") {} //call constructor above
}

public class Foo : AnotherChildClass
{
    public AnotherChildClass(string s) : base(s) {} //base optional

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X