3

コンストラクターの構文とコンストラクター内での例外のスローに関連する質問があります。

CreateAnotherOne() の呼び出しの前に引数 b の ArgumentNullException をスローし、チェック後にコードを複製せずに 2 番目のコンストラクターのように例外をスローする方法は? コードを別のプライベート メソッドに抽出することはできますが、両方のコンストラクタ本体から呼び出す必要があります...これを達成するための他のオプションはありますか?

public class MyClass
{
    public MyClass(IWhatEver a, ISomeThingElse b)
        : this(a, b != null ? b.CreateAnotherOne() : null)
    {
        // or should I call :this(a, b.CreateAnotherOne()) instead? this could cause a NullReferenceException => how to verify that b is not null?
        // don't want to call CallMeFromConstructor() instead of call to other constructor

        // would not do the following (why should I check a/c twice?) and the check is too late here (because already called a method on b, b.CreateAnotherOne())
        if (a == null)
        {
            throw new ArgumentNullException("a");
        }

        if (b == null)
        {
            throw new ArgumentNullException("b");
        }
    }

    public MyClass(IWhatEver c, IAnotherOne d)
    {
        if (c == null)
        {
            throw new ArgumentNullException("c");
        }
        if (d == null)
        {
            throw new ArgumentNullException("d");
        }

        // the cool code comes here, I could put it into
        // the CallMeFromConstructor method but is there another way?
    }
    ...

    private void CallMeFromConstructors()
    {
        // the cool code could be here, too (but is there another way?)
    }

2 番目のコンストラクターを : this(a, b != null ? b.CreateAnotherOne() : null) で呼び出すと、2 番目のコンストラクターの d int に対して ArgumentNullException が発生します。これは私には奇妙に聞こえますが、最初のものを呼び出したので誤解を招く可能性があります (これはスタック トレースでのみ確認できます)。

書けないのが問題

:this(a, b == null ? b.CreateAnotherOne() : throw new ArgumentNullException("b"));

チェックをコンストラクターの本体に入れると、この場合は遅くまでチェックされます。

これを解決するための構文糖のアイデアはありますか?

4

1 に答える 1

3

プライベート メソッドで実行できますが、別のプライベート コンストラクターを作成することもできます。

    private MyClass(IWhatEver a)
    {
        if (a == null)
        {
            throw new ArgumentNullException("a");
        }

        // the cool code comes here, I could put it into
        // the CallMeFromConstructor method but is there another way?
    }

    public MyClass(IWhatEver a, ISomeThingElse b) : this(a)
    {
        if (b == null)
        {
            throw new ArgumentNullException("b");
        }
    }

    public MyClass(IWhatEver a, IAnotherOne b) : this(a)
    {
        if (b == null)
        {
            throw new ArgumentNullException("b");
        }
    }
于 2013-01-31T18:22:14.003 に答える