違い - c# 別のコンストラクタを呼び出す




あるコンストラクタを別のコンストラクタから呼び出す (6)

コンストラクターの連鎖、つまり、 "Base"を使用すると、1つの呼び出しで複数のコンストラクターを呼び出すときに、同じクラスに使用できる関係と "This"を使用できます。

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

readonlyフィールドに値を送る2つのコンストラクタがあります。

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;

}

1つのコンストラクタは値を直接受け取り、もう1つは何らかの計算を行い値を取得してからフィールドを設定します。

今ここにキャッチがあります:

  1. 私は設定コードを複製したくありません。 この場合、フィールドは1つだけ設定されますが、もちろん複数のフィールドが存在する可能性があります。
  2. フィールドを読み込み専用にするには、コンストラクタからそれらを設定する必要があるので、共有コードをユーティリティ関数に「抽出」することはできません。
  3. あるコンストラクタを別のコンストラクタから呼び出す方法はわかりません。

何か案は?


あなたが望むものが、独自のメソッドで初期化を持たなくても満足いくように達成できない場合(例えば、初期化コードの前にあまりにも多くの処理をしたり、try-finallyでラップするなど)コンストラクタは初期化ルーチンへの参照によって読み取り専用変数を渡します。初期化ルーチンは自由に操作することができます。

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

このような:

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

コンストラクタの本体の前に、次のいずれかを使用します。

: base (parameters)

: this (parameters)

例:

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

次に、別のコンストラクタを呼び出し、設定したプロパティをチェックする例を示します。

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

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

私はスーパーキャットの答えを改善しています。 私は次のこともできると思います:

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




constructor