with - sub new in c#




Chiamare il costruttore di base in C# (8)

Se eredito da una classe base e voglio passare qualcosa dal costruttore della classe ereditata al costruttore della classe base, come faccio?

Per esempio,

Se eredito dalla classe Exception, voglio fare qualcosa del genere:

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

Fondamentalmente quello che voglio è essere in grado di passare il messaggio stringa alla classe Exception di base.


È anche possibile eseguire un controllo condizionale con parametri nel costruttore, che consente una certa flessibilità.

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

o

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

È vero utilizzare la base (qualcosa) per chiamare il costruttore della classe base, ma in caso di overload utilizzare la parola chiave this

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

Modifica il tuo costruttore al seguente in modo che chiami correttamente il costruttore della classe base:

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

Nota che un costruttore non è qualcosa che puoi chiamare in qualsiasi momento all'interno di un metodo. Questo è il motivo per cui ricevi degli errori nella tua chiamata nel corpo del costruttore.


Se è necessario chiamare il costruttore base ma non subito perché la nuova classe (derivata) deve eseguire alcune manipolazioni di dati, la soluzione migliore è ricorrere al metodo factory. Quello che devi fare è contrassegnare il tuo costruttore derivato privato, quindi creare un metodo statico nella tua classe che farà tutto il necessario e in seguito chiamerà il costruttore e restituirà l'oggetto.

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

Da linee guida per la progettazione di framework e regole FxCop. :

1. L'eccezione personalizzata dovrebbe avere un nome che termina con Eccezione

    class MyException : Exception

2. L'eccezione dovrebbe essere pubblica

    public class MyException : Exception

3. CA1032: l'eccezione dovrebbe implementare i costruttori standard.

  • Un costruttore pubblico senza parametri.
  • Un costruttore pubblico con un argomento di stringa.
  • Un costruttore pubblico con una stringa ed Eccezione (in quanto può racchiudere un'altra eccezione).
  • Un costruttore di serializzazione protetto se il tipo non è sigillato e privato se il tipo è sigillato. Basato su 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.
      }
    }  
    

o

    [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.
      }
    }  

usando la base puoi chiamare il costruttore della classe 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();

        }
    }

public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}

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

È possibile passare l'eccezione interna a uno dei costruttori.





constructor