Domanda

Se ho ereditare da una classe base e vogliono trasmettere qualcosa dal costruttore della classe ereditata al costruttore della classe base, come devo fare?

Per esempio,

Se ho ereditano dalla classe Exception voglio fare qualcosa di simile a questo:

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

In pratica quello che voglio è essere in grado di passare la stringa messaggio alla base classe di Eccezione.

È stato utile?

Soluzione

Modificare il costruttore al seguente così che si chiama il costruttore della classe base in modo corretto:

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

Nota che un costruttore non è qualcosa che si può chiamare in qualsiasi momento all'interno di un metodo.Per questo motivo si riscontrano errori nella chiamata al costruttore di corpo.

Altri suggerimenti

Si noti che è possibile utilizzare statico metodi per la chiamata al costruttore di 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;
     }
}

Se avete bisogno di chiamare il costruttore di base, ma non subito, perché il nuovo (derivato) classe richiede manipolazione dei dati, la soluzione migliore è ricorrere a metodi factory.Quello che dovete fare è quello di marchio privato derivata costruttore, e poi di realizzare un metodo statico in classe che farà tutto il materiale necessario e poi chiamare il costruttore e restituire 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);
    }
}

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

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
public class MyExceptionClass : Exception
{
    public MyExceptionClass(string message,
      Exception innerException): base(message, innerException)
    {
        //other stuff here
    }
}

È possibile passare eccezione interna di uno dei costruttori.

Da Quadro Di Linee Guida Per La Progettazione e FxCop regole.:

1.Eccezione personalizzato dovrebbe avere un nome che termina con l'Eccezione

    class MyException : Exception

2.L'eccezione deve essere pubblica

    public class MyException : Exception

3. CA1032:Eccezione implementa standard costruttori.

  • Un pubblico costruttore senza parametri.
  • Un costruttore pubblico con un argomento di tipo stringa.
  • Un costruttore pubblico con una corda e l'Eccezione (come si può avvolgere un'altra Eccezione).
  • Una serializzazione costruttore 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.
      }
    }  

È anche possibile effettuare 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)
{
}
class Exception
{
     public Exception(string message)
     {
         [...]
     }
}

class MyExceptionClass : Exception
{
     public MyExceptionClass(string message, string extraInfo)
     : base(message)
     {
         [...]
     }
}
public class MyException : Exception
{
    public MyException() { }
    public MyException(string msg) : base(msg) { }
    public MyException(string msg, Exception inner) : base(msg, inner) { }
}

Come per alcune delle altre risposte elencati qui, è possibile passare parametri al costruttore della classe base.Si consiglia di chiamare il costruttore della classe base all'inizio del costruttore classe ereditata.

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

Faccio notare che nel tuo esempio hai mai fatto uso di extraInfo parametro, così ho pensato che si potrebbe desiderare per concatenare i extraInfo parametro di stringa per la Message di proprietà del tuo eccezione (sembra che questo viene ignorato accettate risposta e il codice nella tua domanda).

Questo si ottiene semplicemente richiamando il costruttore della classe base, e quindi l'aggiornamento di proprietà del Messaggio con le informazioni supplementari.

public class MyException: Exception
{
    public MyException(string message, string extraInfo) : base($"{message} Extra info: {extraInfo}")
    {
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top