De basisconstructor aanroepen in C#

Als ik overneem van een basisklasse en iets wil doorgeven van de constructor van de overgeërfde klasse aan de constructor van de basisklasse, hoe doe ik dat dan?

Als ik bijvoorbeeld erven van de Exception-klasse, wil ik zoiets als dit doen:

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

In principe wil ik het string-bericht kunnen doorgeven aan de basis Exception-klasse.


Antwoord 1, autoriteit 100%

Wijzig uw constructor als volgt zodat deze de constructor van de basisklasse correct aanroept:

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

Merk op dat een constructor niet iets is dat je op elk moment binnen een methode kunt aanroepen. Dat is de reden dat je fouten krijgt in je aanroep in de constructor body.


Antwoord 2, autoriteit 28%

Houd er rekening mee dat u statischemethoden kunt gebruiken binnen de aanroep van de basisconstructor.

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

Antwoord 3, autoriteit 6%

Als je de basisconstructor moet aanroepen, maar niet meteen omdat je nieuwe (afgeleide) klasse wat gegevensmanipulatie moet doen, is de beste oplossing om je toevlucht te nemen tot de fabrieksmethode. Wat u moet doen, is uw afgeleide constructor als privé markeren, vervolgens een statische methode in uw klasse maken die alle noodzakelijke dingen zal doen en later de constructor aanroepen en het object retourneren.

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

Antwoord 4, autoriteit 2%

Het is waar dat je de base(iets) gebruikt om de base class-constructor aan te roepen, maar in geval van overbelasting gebruik je het thistrefwoord

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

Antwoord 5, autoriteit 2%

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

Je kunt innerlijke uitzondering doorgeven aan een van de constructeurs.


Antwoord 6

U kunt ook een voorwaardelijke controle uitvoeren met parameters in de constructor, wat enige flexibiliteit mogelijk maakt.

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

of

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

Antwoord 7

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

Antwoord 8

Volgens sommige van de andere antwoorden die hier worden vermeld, kunt u parameters doorgeven aan de constructor van de basisklasse. Het wordt aangeraden om de constructor van je basisklasse aan het begin van de constructor voor je geërfde klasse aan te roepen.

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

Ik merk op dat je in je voorbeeld nooit de parameter extraInfohebt gebruikt, dus ik nam aan dat je de stringparameter extraInfozou willen samenvoegen met de Messageeigenschap van uw uitzondering (het lijkt erop dat dit wordt genegeerd in het geaccepteerde antwoord en de code in uw vraag).

Dit wordt eenvoudig bereikt door de constructor van de basisklasse aan te roepen en vervolgens de eigenschap Message bij te werken met de extra info.

public class MyException: Exception
{
    public MyException(string message, string extraInfo) : base($"{message} Extra info: {extraInfo}")
    {
    }
}

Antwoord 9

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

Antwoord 10

Door nieuwere C#-functies te gebruiken, namelijk out var, kun je de statische fabrieksmethode verwijderen.
Ik ben er net (per ongeluk) achter gekomen dat de var-parameter van methoden die inse base-“call” wordt genoemd, naar de body van de constructor stroomt.

Voorbeeld, deze basisklasse gebruiken waaruit u wilt afleiden:

public abstract class BaseClass
{
    protected BaseClass(int a, int b, int c)
    {
    }
}

De niet-compilerende pseudo-code die u wilt uitvoeren:

public class DerivedClass : BaseClass
{
    private readonly object fatData;
    public DerivedClass(int m)
    {
        var fd = new { A = 1 * m, B = 2 * m, C = 3 * m };
        base(fd.A, fd.B, fd.C); // base-constructor call
        this.fatData = fd;
    }
}

En de oplossing door een statische privéhulpmethode te gebruiken die alle vereiste basisargumenten produceert (plus aanvullende gegevens indien nodig) en zonder een statische fabrieksmethode te gebruiken, gewoon een constructor naar buiten:

public class DerivedClass : BaseClass
{
    private readonly object fatData;
    public DerivedClass(int m)
        : base(PrepareBaseParameters(m, out var b, out var c, out var fatData), b, c)
    {
        this.fatData = fatData;
        Console.WriteLine(new { b, c, fatData }.ToString());
    }
    private static int PrepareBaseParameters(int m, out int b, out int c, out object fatData)
    {
        var fd = new { A = 1 * m, B = 2 * m, C = 3 * m };
        (b, c, fatData) = (fd.B, fd.C, fd); // Tuples not required but nice to use
        return fd.A;
    }
}

Antwoord 11

public class Car
{
     public Car(string model)
     {
        Console.WriteLine(model);
     }
}
public class Mercedes : Car
{
     public Mercedes(string model): base(model)
     {
     }
}

Gebruik:

Mercedes mercedes = new Mercedes("CLA Shooting Brake");

Uitgang: CLA-opnamemrem


12

Toevoegen : base("string or something")na de constructeur, niet in zijn lichaam.

public class MyException : System.Exception {
    public MyException(string msg) : base(msg) {
        // code here
    }
}

Other episodes