1672 votes

Appel du constructeur de base en C#

Si j'hérite d'une classe de base et que je veux passer quelque chose du constructeur de la classe héritée au constructeur de la classe de base, comment dois-je faire ?

Par exemple, si j'hérite de la classe Exception, je veux faire quelque chose comme ceci :

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     {
         //This is where it's all falling apart
         base(message);
     }
}

En fait, ce que je veux, c'est pouvoir transmettre un message de type chaîne à la classe de base Exception.

32 votes

Il est également intéressant de noter que vous pouvez enchaîner les constructeurs dans votre classe actuelle en substituant this para base .

0 votes

3 votes

Au lieu de dire "tout s'écroule", il est beaucoup plus utile d'afficher l'erreur que vous obtenez.

2043voto

Jon Limjap Points 46429

Modifiez votre constructeur comme suit afin qu'il appelle correctement le constructeur de la classe de base :

public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message, string extrainfo) : base(message)
    {
        //other stuff here
    }
}

Notez qu'un constructeur n'est pas quelque chose que vous pouvez appeler à tout moment dans une méthode. C'est la raison pour laquelle vous obtenez des erreurs dans votre appel dans le corps du constructeur.

63 votes

Je pense que vous n'avez pas compris. Le problème concerne l'appel d'un constructeur de base à mi-chemin du constructeur surchargé. Peut-être que le type de données du constructeur de base n'est pas le même ou que vous voulez faire un peu de moulage de données avant de les passer dans la chaîne. Comment réaliser un tel exploit ?

225 votes

Si vous avez besoin d'appeler le constructeur de base au milieu de la surcharge, alors extrayez-le vers une méthode réelle de la classe de base que vous pouvez appeler explicitement. L'hypothèse avec les constructeurs de base est qu'ils sont absolument nécessaires pour créer un objet en toute sécurité, donc la base sera appelée en premier, toujours.

37 votes

Il es juste une méthode que l'on peut appeler à tout moment, dans le cadre de l'IL. Il se trouve que le C# impose des restrictions supplémentaires.

573voto

Axl Points 3077

Notez que vous pouvez utiliser statique dans l'appel au constructeur de base.

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo) : 
         base(ModifyMessage(message, extraInfo))
     {
     }

     private static string ModifyMessage(string message, string extraInfo)
     {
         Trace.WriteLine("message was " + message);
         return message.ToLowerInvariant() + Environment.NewLine + extraInfo;
     }
}

6 votes

La classe Exception est tellement verrouillée que je me suis retrouvé à faire cela quelques fois, mais je note également que ce n'est pas quelque chose que vous devriez faire si vous pouvez l'éviter.

0 votes

Désolé, je suis un débutant en C#. Pourquoi appelez-vous Trace.WriteLine("message was " + message) ?

7 votes

@kdbanman Cela produit juste un message de débogage. Aucun objectif fonctionnel pertinent.

111voto

armanali Points 875

Si vous avez besoin d'appeler le constructeur de base, mais pas tout de suite, parce que votre nouveau (dérivée) de la classe besoin de faire un peu de manipulation de données, la meilleure solution est de recourir à la méthode de fabrique. Ce que vous devez faire est de marque privée de votre dérivé du constructeur, puis faire une méthode statique dans votre classe qui va faire toutes les choses nécessaires et, plus tard, appelez le constructeur et le retour de l'objet.

public class MyClass : BaseClass
{
    private MyClass(string someString) : base(someString)
    {
        //your code goes in here
    }

    public static MyClass FactoryMethod(string someString)
    {
        //whatever you want to do with your string before passing it in
        return new MyClass(someString);
    }
}

8 votes

Cela pourrait potentiellement viole les principes SOLID (SRP), car la responsabilité de la création de la classe est encapsulée avec toute autre responsabilité que la classe était censée prendre en charge. Une fabrique abstraite pourrait être utilisée mais pourrait ajouter une complexité inutile à un code simple. Bien sûr, la violation des principes SOLID n'est pas un problème si vous connaissez le compromis et les conséquences sur votre architecture (et comment résoudre les problèmes futurs qui pourraient résulter de votre décision de conception).

42voto

Janus Pedersen Points 29

Il est vrai que l'utilisation du base (quelque chose) pour appeler le constructeur de la classe de base, mais en cas de surcharge, utilisez la fonction this mot-clé

public ClassName() : this(par1,par2)
{
// do not call the constructor it is called in the this.
// the base key- word is used to call a inherited constructor   
} 

// Hint used overload as often as needed do not write the same code 2 or more times

11 votes

Je vois ce que vous essayez d'expliquer, et vous avez raison. Si vous avez deux constructeurs dans une classe, vous pouvez en référencer un à partir de l'autre en utilisant le mot-clé "this" de la même manière que vous utilisez "base" pour appeler le constructeur hérité. Cependant, ce n'est pas ce que l'OP a demandé, donc ce n'est pas vraiment l'endroit pour ajouter ceci.

32voto

SnowBEE Points 465
public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message,
      Exception innerException): base(message, innerException)
    {
        //other stuff here
    }
}

Vous pouvez passer une exception interne à l'un des constructeurs.

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