it-swarm.com.de

Rufen Sie einen Konstruktor aus einem anderen auf

Ich habe zwei Konstruktoren, die Werte zu Readonly-Feldern liefern.

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;

}

Ein Konstruktor empfängt die Werte direkt, und der andere berechnet etwas und erhält die Werte und setzt dann die Felder.

Hier ist der Haken:

  1. Ich möchte den Einstellungscode Nicht kopieren. In diesem Fall ist nur ein Feld gesetzt, aber es kann natürlich auch Mehr als ein Feld sein.
  2. Um die Felder schreibgeschützt zu machen, muss ich sie aus dem Konstruktor setzen, also kann ich den gemeinsam genutzten Code nicht in eine Dienstprogrammfunktion extrahieren.
  3. Ich weiß nicht, wie ich einen Konstruktor von einem anderen aufrufen kann.

Irgendwelche Ideen?

834
Avi

So was:

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

Wenn das, was Sie wollen, nicht zufriedenstellend erreicht werden kann, ohne die Initialisierung in einer eigenen Methode zu haben (z. B. weil Sie vor dem Initialisierungscode zu viel tun möchten oder ihn in ein Try-finally oder etwas anderes einfassen möchten), können Sie eines oder alle haben Konstruktoren übergeben die Readonly-Variablen anhand einer Initialisierungsroutine, die sie dann nach Belieben manipulieren kann.

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

Verwenden Sie vor dem Rumpf des Konstruktors entweder:

: base (parameters)

: this (parameters)

Beispiel:

public class People: User
{
   public People (int EmpID) : base (EmpID)
   {
      // Add more statements here.
   }
}
50
Sudantha

Ich verbessere die Antwort von Supercat. Ich denke, das Folgende kann auch gemacht werden:

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);
    }
}
9
Faisal Mq

Hier ist ein Beispiel, das einen anderen Konstruktor aufruft und dann die von ihm gesetzte Eigenschaft überprüft.

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

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

Ja, du kannst eine andere Methode vor der Aufrufbasis oder so aufrufen!

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

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

}
4

Wenn Sie eine Klasse von einer Basisklasse erben, können Sie den Basisklassenkonstruktor durch Instantiieren der abgeleiteten Klasse aufrufen

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

Ausgabe des Beispielprogramms ist

50 10 20


Sie können auch das this-Schlüsselwort verwenden, um einen Konstruktor von einem anderen Konstruktor aus aufzurufen

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

Die Ausgabe dieses Beispielprogramms ist 

20

1
Lineesh K Mohan

Constructor-Verkettung Sie können "Base" für "Eine Beziehung" und "This" für dieselbe Klasse verwenden, wenn Sie mehrere Constructor in einem einzigen Aufruf aufrufen möchten.

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