1856 Stimmen

Aufrufen des Basiskonstruktors in C#

Wenn ich von einer Basisklasse erbe und etwas vom Konstruktor der geerbten Klasse an den Konstruktor der Basisklasse übergeben möchte, wie mache ich das?

Wenn ich z. B. von der Klasse Exception erbe, möchte ich so etwas wie das Folgende tun:

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

Im Grunde, was ich will, ist in der Lage, die Zeichenfolge Nachricht an die Basisklasse Exception übergeben.

37 Stimmen

Es ist auch erwähnenswert, dass Sie Konstruktoren in Ihrer aktuellen Klasse verketten können, indem Sie this para base .

0 Stimmen

5 Stimmen

Anstatt zu sagen, "es fällt alles auseinander", ist es viel hilfreicher, einfach die Fehlermeldung zu posten, die Sie erhalten

2225voto

Jon Limjap Punkte 92084

Ändern Sie Ihren Konstruktor so ab, dass er den Konstruktor der Basisklasse korrekt aufruft:

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

Beachten Sie, dass Sie einen Konstruktor nicht jederzeit innerhalb einer Methode aufrufen können. Das ist der Grund, warum Sie bei Ihrem Aufruf im Konstruktorkörper Fehler erhalten.

77 Stimmen

Ich glaube, Sie haben das Thema verfehlt. Das Problem war der Aufruf eines Basiskonstruktors auf halbem Weg durch den überschriebenen Konstruktor. Vielleicht ist der Datentyp des Basiskonstruktors nicht derselbe oder Sie möchten die Daten anpassen, bevor Sie sie in der Kette weitergeben. Wie würden Sie ein solches Kunststück vollbringen?

253 Stimmen

Wenn Sie den Basiskonstruktor in der Mitte der Überschreibung aufrufen müssen, dann extrahieren Sie ihn in eine tatsächliche Methode der Basisklasse, die Sie explizit aufrufen können. Bei Basiskonstruktoren wird davon ausgegangen, dass sie absolut notwendig sind, um ein Objekt sicher zu erstellen, daher wird der Basiskonstruktor immer zuerst aufgerufen.

41 Stimmen

Es es nur eine Methode, die Sie jederzeit aufrufen können, IL-mäßig. C# nur geschieht, um zusätzliche Einschränkungen auf diese oben setzen.

641voto

Axl Punkte 7802

Beachten Sie, dass Sie statisch Methoden innerhalb des Aufrufs des Basiskonstruktors.

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

8 Stimmen

Die Klasse Exception ist so verschlossen, dass ich mich dabei ertappe, dies ein paar Mal zu tun, aber auch zu beachten, es ist nicht etwas, das Sie tun sollten, wenn Sie es vermeiden können.

0 Stimmen

Entschuldigung, ich bin C#-Neuling. Warum nennen Sie Sie Trace.WriteLine("message was " + message) ?

7 Stimmen

@kdbanman Das gibt nur eine Fehlermeldung aus. Kein relevanter funktionaler Zweck.

124voto

aalimian Punkte 2725

Wenn Sie den Basiskonstruktor aufrufen müssen, aber nicht sofort, weil Ihre neue (abgeleitete) Klasse einige Datenmanipulationen vornehmen muss, ist die beste Lösung, auf die Factory-Methode zurückzugreifen. Sie müssen Ihren abgeleiteten Konstruktor als privat kennzeichnen und dann eine statische Methode in Ihrer Klasse erstellen, die alle notwendigen Aufgaben übernimmt und später den Konstruktor aufruft und das Objekt zurückgibt.

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

13 Stimmen

Dies könnte Möglicherweise verstößt gegen die SOLID-Grundsätze (SRP), da die Verantwortung für die Erstellung der Klasse mit allen anderen Verantwortlichkeiten, die die Klasse übernehmen sollte, gekapselt ist. Eine abstrakte Fabrik könnte verwendet werden, aber sie könnte den einfachen Code unnötig kompliziert machen. Natürlich ist ein Verstoß gegen die SOLID-Prinzipien in Ordnung, wenn man den Kompromiss und die Auswirkungen auf die Architektur kennt (und weiß, wie man zukünftige Probleme beheben kann, die sich aus der Entwurfsentscheidung ergeben könnten).

50voto

Janus Pedersen Punkte 467

Es ist richtig, die base (irgendetwas), um den Konstruktor der Basisklasse aufzurufen, aber im Falle einer Überladung verwenden Sie die this Stichwort

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

13 Stimmen

Ich verstehe, was Sie zu erklären versuchen, und Sie haben Recht. Wenn Sie zwei Konstruktoren in einer Klasse haben, können Sie einen von dem anderen referenzieren, indem Sie das Schlüsselwort "this" verwenden, ähnlich wie Sie "base" verwenden, wenn Sie den geerbten Konstruktor aufrufen. Dies ist jedoch nicht das, wonach der Auftraggeber gefragt hat, also ist dies nicht der richtige Ort, um dies hinzuzufügen.

0 Stimmen

the keyword 'base' is not valid in this context

35voto

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

Sie können innere Ausnahmen an einen der Konstruktoren übergeben.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X