c# strip - Chiama un costruttore da un altro




html agility (8)

Quando si eredita una classe da una classe base, è possibile richiamare il costruttore della classe base creando un'istanza della classe derivata

class sample
{
    public int x;

    public sample(int value)
    {
        x = value;
    }
}

class der : sample
{
    public int a;
    public int b;

    public der(int value1,int value2) : base(50)
    {
        a = value1;
        b = value2;
    }
}

class run 
{
    public static void Main(string[] args)
    {
        der obj = new der(10,20);

        System.Console.WriteLine(obj.x);
        System.Console.WriteLine(obj.a);
        System.Console.WriteLine(obj.b);
    }
}

L'output del programma di esempio è

50 10 20

È inoltre possibile utilizzare this parola chiave per richiamare un costruttore da un altro costruttore

class sample
{
    public int x;

    public sample(int value) 
    {
        x = value;
    }

    public sample(sample obj) : this(obj.x) 
    {
    }
}

class run
{
    public static void Main(string[] args) 
    {
        sample s = new sample(20);
        sample ss = new sample(s);

        System.Console.WriteLine(ss.x);
    }
}

L'output di questo programma di esempio è

20

Ho due costruttori che alimentano valori in campi di sola lettura.

class Sample
{
    public Sample(string theIntAsString)
    {
        int i = int.Parse(theIntAsString);

        _intField = i;
    }

    public Sample(int theInt)
    {
        _intField = theInt;
    }


    public int IntProperty
    {
        get { return _intField; }
    }
    private readonly int _intField;

}

Un costruttore riceve direttamente i valori e l'altro esegue alcuni calcoli e ottiene i valori, quindi imposta i campi.

Ora ecco il trucco:

  1. Non voglio duplicare il codice di impostazione. In questo caso, è impostato un solo campo, ma ovviamente potrebbero essercene più di uno.
  2. Per rendere i campi in sola lettura, ho bisogno di impostarli dal costruttore, quindi non posso "estrarre" il codice condiviso in una funzione di utilità.
  3. Non so come chiamare un costruttore da un altro.

Qualche idea?


Sto migliorando la risposta del supercat. Immagino che quanto segue possa anche essere fatto:

class Sample
{
    private readonly int _intField;
    public int IntProperty
    {
        get { return _intField; }
    }

    void setupStuff(ref int intField, int newValue)
    {
        //Do some stuff here based upon the necessary initialized variables.
        intField = newValue;
    }

    public Sample(string theIntAsString, bool? doStuff = true)
    {
        //Initialization of some necessary variables.
        //==========================================
        int i = int.Parse(theIntAsString);
        // ................
        // .......................
        //==========================================

        if (!doStuff.HasValue || doStuff.Value == true)
           setupStuff(ref _intField,i);
    }

    public Sample(int theInt): this(theInt, false) //"false" param to avoid setupStuff() being called two times
    {
        setupStuff(ref _intField, theInt);
    }
}

Sì, puoi chiamare un altro metodo prima della base di chiamata o questo!

public class MyException : Exception
{
    public MyException(int number) : base(ConvertToString(number)) 
    {
    }

    private static string ConvertToString(int number) 
    { 
      return number.toString()
    }

}

Se quello che vuoi non può essere ottenuto in modo soddisfacente senza l'inizializzazione nel suo metodo (es. Perché vuoi fare troppo prima del codice di inizializzazione, o avvolgerlo in un tentativo-finalmente, o qualsiasi altra cosa) puoi averne uno o tutti i costruttori passano le variabili readonly in riferimento a una routine di inizializzazione, che sarà quindi in grado di manipolarle a volontà.

class Sample
{
    private readonly int _intField;
    public int IntProperty
    {
        get { return _intField; }
    }

    void setupStuff(ref int intField, int newValue)
    {
        intField = newValue;
    }

    public Sample(string theIntAsString)
    {
        int i = int.Parse(theIntAsString);
        setupStuff(ref _intField,i);
    }

    public Sample(int theInt)
    {
        setupStuff(ref _intField, theInt);
    }
}

Ecco un esempio che chiama un altro costruttore, quindi controlla la proprietà che ha impostato.

    public SomeClass(int i)
    {
        I = i;
    }

    public SomeClass(SomeOtherClass soc)
        : this(soc.J)
    {
        if (I==0)
        {
            I = DoSomethingHere();
        }
    }

Concatenamento del costruttore, ovvero è possibile utilizzare "Base" per È una relazione e "Questo" è possibile utilizzare per la stessa classe, quando si desidera chiamare più Costruttore in una singola chiamata.

  class BaseClass
{
    public BaseClass():this(10)
    {
    }
    public BaseClass(int val)
    {
    }
}
    class Program
    {
        static void Main(string[] args)
        {
            new BaseClass();
            ReadLine();
        }
    }

Come questo:

public Sample(string str) : this(int.Parse(str)) {
}

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






c# constructor