1316 Stimmen

Aufruf eines Konstruktors aus einem anderen

Ich habe zwei Konstruktoren, die Werte in schreibgeschützte Felder eingeben.

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

    public Sample(int theInt) => _intField = theInt;
    public int IntProperty    => _intField;

    private readonly int _intField;
}

Der eine Konstruktor empfängt die Werte direkt, der andere führt eine Berechnung durch, ermittelt die Werte und setzt dann die Felder.

Und jetzt kommt der Haken:

  1. Ich möchte nicht die Code einstellen. In diesem Fall wird nur ein Feld gesetzt, aber es kann natürlich auch mehr als eines sein.
  2. Um die Felder schreibgeschützt zu machen, benötige ich muss ich sie im Konstruktor setzen, also kann ich den gemeinsamen Code nicht in eine eine Utility-Funktion.
  3. Ich weiß nicht, wie man einen anruft Konstruktor von einem anderen aufrufen kann.

Irgendwelche Ideen?

9voto

Maurício Júnior Punkte 190

Ja, Sie können andere Methoden vor dem Aufruf von Base oder This aufrufen!

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

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

}

8voto

SUNIL DHAPPADHULE Punkte 2413

Verkettung von Konstruktoren d.h. Sie können "Base" für Is a relationship und "This" für dieselbe Klasse verwenden, wenn Sie mehrere Constructor in einem einzigen Aufruf aufrufen wollen.

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

5voto

Lineesh K Mohan Punkte 1644

Wenn Sie eine Klasse von einer Basisklasse erben, können Sie den Konstruktor der Basisklasse aufrufen, indem Sie die abgeleitete Klasse instanziieren

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 Beispielprogramm ist

50 10 20


Sie können auch Folgendes verwenden this Schlüsselwort, 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 dieser Beispielprogramm es

20

2voto

Fehlerbehandlung und Wiederverwendbarkeit des Codes sind der Schlüssel. Ich habe die Validierung von String zu Int hinzugefügt und es ist möglich, bei Bedarf weitere Typen hinzuzufügen. Dieses Problem mit einer wiederverwendbaren Lösung zu lösen, könnte so aussehen:

public class Sample
{
    public Sample(object inputToInt)
    {
        _intField = objectToInt(inputToInt);
    }

    public int IntProperty => _intField;

    private readonly int _intField;
}

public static int objectToInt(object inputToInt)
{
    switch (inputToInt)
        {
            case int inputInt:
                return inputInt;
            break;
            case string inputString:
            if (!int.TryParse(inputString, out int parsedInt))
            {
                throw new InvalidParameterException($"The input {inputString} could not be parsed to int");
            }
            return parsedInt;

            default:
                throw new InvalidParameterException($"Constructor do not support {inputToInt.GetType().Name}");
            break;
        }
}

1voto

Erdogan Kurtur Punkte 3443

Bitte, bitte, bitte, bitte versuchen Sie das nicht zu Hause, bei der Arbeit oder sonst wo.

Dies ist ein Weg, um ein sehr spezifisches Problem zu lösen, und ich hoffe, dass Sie das nicht haben werden.

Ich poste dies, da es technisch gesehen eine Antwort ist und eine andere Perspektive darstellt.

Ich wiederhole, verwenden Sie es unter keinen Umständen. Der Code muss mit LINQPad ausgeführt werden.

void Main()
{
    (new A(1)).Dump();
    (new B(2, -1)).Dump();

    var b2 = new B(2, -1);
    b2.Increment();

    b2.Dump();
}

class A 
{
    public readonly int I = 0;

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

class B: A
{
    public int J;
    public B(int i, int j): base(i)
    {
        J = j;
    }

    public B(int i, bool wtf): base(i)
    {
    }

    public void Increment()
    {
        int i = I + 1;

        var t = typeof(B).BaseType;
        var ctor = t.GetConstructors().First();

        ctor.Invoke(this, new object[] { i });
    }
}

Da der Konstruktor eine Methode ist, können Sie ihn mit Reflection aufrufen. Jetzt denken Sie entweder mit Portalen, oder visualisieren Sie ein Bild von einer Dose Würmer.

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