web-dev-qa-db-fra.com

Appeler un constructeur d'un autre

J'ai deux constructeurs qui alimentent des valeurs en lecture seule des champs.

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 constructeur reçoit les valeurs directement et l'autre effectue des calculs et obtient les valeurs, puis définit les champs.

Maintenant, voici le piège:

  1. Je ne veux pas dupliquer le code de réglage Dans ce cas, un seul champ Est défini, mais il peut bien sûr y avoir plus d'un.
  2. Pour rendre les champs en lecture seule, j'ai besoin de les définir à partir du constructeur, donc Je ne peux pas "extraire" le code partagé en Une fonction utilitaire.
  3. Je ne sais pas comment appeler un Constructeur d'un autre.

Des idées?

834
Avi

Comme ça:

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

Si ce que vous voulez ne peut pas être réalisé de manière satisfaisante sans avoir l’initialisation dans sa propre méthode (par exemple parce que vous voulez en faire trop avant le code d’initialisation, ou l’envelopper dans un essai final ou autre), vous pouvez avoir tout Les constructeurs transmettent les variables en lecture seule en se référant à une routine d’initialisation, qui pourra ensuite les manipuler à 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);
    }
}
143
supercat

Avant le corps du constructeur, utilisez soit:

: base (parameters)

: this (parameters)

Exemple:

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

J'améliore la réponse de Supercat. Je suppose que ce qui suit peut aussi être fait:

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

Voici un exemple qui appelle un autre constructeur, puis vérifie la propriété qu'il a définie.

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

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

Ouais, vous pouvez appeler une autre méthode avant de la base d’appel ou ceci!

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

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

}
4

Lorsque vous héritez d'une classe d'une classe de base, vous pouvez appeler le constructeur de la classe de base en instanciant la classe dérivée.

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

Le résultat du exemple de programme est

50 10 20


Vous pouvez également utiliser le mot clé this pour appeler un constructeur à partir d'un autre constructeur.

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

Le résultat de ce exemple de programme est 

20

1
Lineesh K Mohan

Chaîne de constructeur i.e, vous pouvez utiliser "Base" pour Est une relation et "Ceci", vous pouvez utiliser pour la même classe, lorsque vous souhaitez appeler plusieurs constructeurs en un seul appel.

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