web-dev-qa-db-ja.com

それ自体でコンストラクタを呼び出せないのはなぜですか?

クラスNumberRangeをJava=からC#に移植しています。

私はこれを書いています constructor と私はそれ自体でコンストラクタを呼び出すことができるかどうか疑問に思います。このようなもの:

public NumberRange(Double num1, Double num2)
{
    if (num1 <= num2)
    {
        Min = num1;
        Max = num2;
    }
    else
    {
        NumberRange(num2, num1);
        // Min = num2;
        // Max = num1;
    }
}

。NETFiddle

これは大したことではありませんが、私は興味があります。クラスの作成中にスタックオーバーフローを作成することで、コンストラクターの混乱を防ぐためだと思います。

では、なぜそれ自体でコンストラクタを呼び出せないのでしょうか?

編集:

私の質問は、「なぜ」ではなく「なぜ」についてであったことを思い出します。私がこれをどのように実装したかを自問する場合は、私のコード here を読んでください。

問題は再帰ではなく、コンストラクターの呼び出しにあるようです。下記参照:

class NumberRange
{
    public double Min { get; set; }
    public double Max { get; set; }

    public NumberRange(double num1, double num2)
    {
        if (num1 <= num2)
        {
            Min = num1;
            Max = num2;
        }
        else
            NumberRange(num2, num1); // illegal!!
    }

    public void AFunction()
    {
        NumberRange(1, 2); // also illegal!!
        this.NumberRange(1, 2); // 'this' keyword doesn't help
    }
}

そして:

new NumberRange(1, 2).NumberRange(2, 1); // can't invoke the constructor on an object either

明らかにあなたの場合、再帰は完全に不要でしたが、「再帰可能」でなければならないコードがある場合、またはクラスをインスタンス化するコンテキストの外でのみ利用できる場合、そのコードは非コンストラクタ関数内にある必要があります。

C#でコンストラクターからメソッドを呼び出してもよい理由については、 this の回答を参照してください。 (要するに、C#は、望み通りにctorで仮想メソッド呼び出しを処理します。)

1

コンストラクターからコンストラクターを呼び出すことができますが、別の構文が必要であり、別のコンストラクターを呼び出す必要があります。 2つを区別するために、プライベートコンストラクターの署名を意図的に変更しました。論理的に同じ署名を持つ必要があるため、この例では適切ではありません

public NumberRange(Double num1, Double num2) 
    : this(Math.Min(num1, num2), Math.Max(num1, num2), true) { }
private NumberRange(Double num1, Double num2, bool differentSignature){         
    Min = num1; 
    Max = num2;
}
6
Sign