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 faire?

par exemple,

si j'hérite de la classe D'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);
     }
}

ce que je veux, C'est pouvoir passer le message string à la classe D'Exception de base.

1192
demandé sur Peter Mortensen 2008-08-15 11:39:23

11 réponses

modifier votre constructeur pour 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.

1516
répondu Jon Limjap 2008-08-15 07:48:56

notez que vous pouvez utiliser les méthodes statiques 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;
     }
}
431
répondu Axl 2015-08-31 17:17:17

si vous devez appeler le constructeur de base mais pas tout de suite parce que votre nouvelle classe (dérivée) a besoin de faire quelques manipulations de données, la meilleure solution est de recourir à la méthode d'usine. Ce que vous devez faire est de marquer privé votre constructeur dérivé, puis faire une méthode statique dans votre classe qui fera toutes les choses nécessaires et plus tard appeler le constructeur et retourner 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);
    }
}
80
répondu armanali 2013-04-07 20:52:07
public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message,
      Exception innerException): base(message, innerException)
    {
        //other stuff here
    }
}

vous pouvez passer l'exception intérieure à l'un des constructeurs.

22
répondu SnowBEE 2009-12-04 05:03:34

il est vrai d'utiliser le base (quelque chose) pour appeler le constructeur de classe de base, mais en cas de surcharge utiliser le 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
19
répondu Janus Pedersen 2018-04-09 11:46:52

à Partir de Cadre des lignes Directrices de Conception et les règles FxCop. :

1. Custom Exception devrait avoir un nom qui se termine avec Exception

    class MyException : Exception

2. L'Exception devrait être publique

    public class MyException : Exception

3. CA1032: Exception devrait implémenter les constructeurs standards.

  • Un public constructeur sans paramètre.
  • un constructeur public avec un argument de chaîne.
  • un constructeur public avec une chaîne et une Exception (comme il peut envelopper une autre Exception).
  • constructeur de sérialisation protégé si le type n'est pas scellé et privé si le type est scellé. Basé sur MSDN :

    [Serializable()]
    public class MyException : Exception
    {
      public MyException()
      {
         // Add any type-specific logic, and supply the default message.
      }
    
      public MyException(string message): base(message) 
      {
         // Add any type-specific logic.
      }
      public MyException(string message, Exception innerException): 
         base (message, innerException)
      {
         // Add any type-specific logic for inner exceptions.
      }
      protected MyException(SerializationInfo info, 
         StreamingContext context) : base(info, context)
      {
         // Implement type-specific serialization constructor logic.
      }
    }  
    

ou

    [Serializable()]
    public sealed class MyException : Exception
    {
      public MyException()
      {
         // Add any type-specific logic, and supply the default message.
      }

      public MyException(string message): base(message) 
      {
         // Add any type-specific logic.
      }
      public MyException(string message, Exception innerException): 
         base (message, innerException)
      {
         // Add any type-specific logic for inner exceptions.
      }
      private MyException(SerializationInfo info, 
         StreamingContext context) : base(info, context)
      {
         // Implement type-specific serialization constructor logic.
      }
    }  
12
répondu Fab 2016-01-24 07:34:21

vous pouvez également faire un contrôle conditionnel avec les paramètres dans le constructeur, ce qui permet une certaine flexibilité.

public MyClass(object myObject=null): base(myObject ?? new myOtherObject())
{
}

ou

public MyClass(object myObject=null): base(myObject==null ? new myOtherObject(): myObject)
{
}
9
répondu wchoward 2018-06-11 10:47:32
class Exception
{
     public Exception(string message)
     {
         [...]
     }
}

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     : base(message)
     {
         [...]
     }
}
4
répondu Tutankhamen 2015-02-26 04:11:37
public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}
4
répondu Donat Sasin 2017-03-22 13:10:47

comme pour certaines des autres réponses énumérées ici, vous pouvez passer des paramètres dans le constructeur de classe de base. Il est conseillé d'appeler votre constructeur de classe de base au début de l'constructeur de votre classe héritée.

public class MyException : Exception
{
    public MyException(string message, string extraInfo) : base(message)
    {
        this.Message = $"{message} Extra info: {extraInfo}";
        // You can omit the 'this.' portion above...
    }
}

je note que dans votre exemple vous n'avez jamais utilisé le paramètre extraInfo , donc j'ai supposé que vous pourriez vouloir concaténer le paramètre extraInfo à la propriété Message de votre exception (il semble que ce est ignorée dans la réponse acceptée et le code dans votre question).

cela est simplement obtenu en invoquant le constructeur de la classe de base, puis en mettant à jour la propriété Message avec les informations supplémentaires.

alternativement, comme la propriété Message est héritée de la classe de base, vous n'avez même pas à appeler explicitement le constructeur de la classe de base. Vous pouvez simplement mettre à jour la propriété Message directement à partir du constructeur de votre classe héritée, comme ceci:

public class MyException : Exception
{
    public MyException(string message, string extraInfo)
    {
        this.Message = $"{message} Extra info: {extraInfo}";
        // You can omit the 'this.' portion above...
    }
}
4
répondu Daffy Punk 2017-07-23 21:04:22

en utilisant la base vous pouvez appeler le constructeur de la classe de base

class BaseClass
    {

    public BaseClass(int val)
    {
        Console.WriteLine($"{nameof(BaseClass) } constructor");
    }
   }

    class DerivedClass : BaseClass
    {
    public DerivedClass() : base(10)
    {
        Console.WriteLine($"{nameof(DerivedClass) } constructor");
    }
    }
    class Program
    {
        static void Main(string[] args)
        {
        BaseClass baseClass = new DerivedClass();
          Console.ReadLine();

        }
    }
0
répondu Sunil Dhappadhule 2018-10-10 07:50:56