如何在调用其他构造函数之前抛出ArgumentNullException

时间:2013-01-31 18:16:34

标签: c# syntax exception-handling constructor

我有一个与构造函数的语法相关的问题,并在构造函数中抛出异常。

如何在调用CreateAnotherOne()之前抛出参数b的ArgumentNullException,并在第二个构造函数中抛出异常,而不会在检查后复制代码?我可以将代码提取到一个单独的私有方法中,但我需要从两个构造函数体中调用它...还有其他选项来实现这个吗?

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

如果我用第二个构造函数调用:this(a,b!= null?b.CreateAnotherOne():null)我会得到第二个构造函数的d int的ArgumentNullException。这听起来很奇怪,可能会产生误导,因为我调用了第一个(只能在堆栈跟踪中看到这个)。

问题在于我无法写

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

如果我将检查放入构造函数的主体中,则会在这种情况下检查它。

解决这个问题的任何语法糖想法?

1 个答案:

答案 0 :(得分: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");
        }
    }