Pregunta Llamar a un constructor de otro


Tengo dos constructores que alimentan valores a campos de solo lectura.

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 constructor recibe los valores directamente, y el otro hace un cálculo y obtiene los valores, luego establece los campos.

Ahora aquí está el truco:

  1. No quiero duplicar el código de configuración. En este caso, solo uno campo está establecido, pero, por supuesto, puede haber bien sea más de uno.
  2. Para hacer los campos de solo lectura, necesito para configurarlos desde el constructor, por lo No puedo "extraer" el código compartido para una función de utilidad.
  3. No sé cómo llamar a uno constructor de otro.

¿Algunas ideas?


759
2017-10-24 16:06


origen


Respuestas:


Me gusta esto:

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

1284
2017-10-24 16:09



Si lo que desea no se puede lograr satisfactoriamente sin tener la inicialización en su propio método (por ejemplo, porque desea hacer demasiado antes del código de inicialización, o envolverlo en una prueba final, o lo que sea) puede tener cualquiera o todos los constructores pasan las variables de solo lectura por referencia a una rutina de inicialización, que luego podrá manipularlos a voluntad.

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

131
2017-07-22 20:52



Antes del cuerpo del constructor, usa:

: base (parameters)

: this (parameters)

Ejemplo:

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

48
2017-10-24 16:12



Estoy mejorando la respuesta de supercat. Supongo que también se puede hacer lo siguiente:

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

8
2017-11-28 13:07



Aquí hay un ejemplo que llama a otro constructor, luego verifica la propiedad que ha establecido.

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

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

6
2018-05-23 00:17



Sí, puedes llamar a otro método antes de la base de llamadas o esto!

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

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

}

4
2018-06-07 20:42



Cuando hereda una clase de una clase base, puede invocar el constructor de la clase base creando una instancia de la clase derivada

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

Salida de la programa de ejemplo es

50 10 20


También puedes usar this palabra clave para invocar un constructor de otro constructor

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

El resultado de esto programa de ejemplo es

20


1
2018-03-31 03:52