在调用base之前检查构造函数参数是否为null

Kla*_*sen 34 c#

我通常以下列方式检查构造函数参数的空值:

public class SomeClass(SomeArgument someArgument)
{
     if(someArgument == null) throw new ArgumentNullException("someArgument");
}
Run Code Online (Sandbox Code Playgroud)

但是说我有一个继承自另一个类的类:

public abstract class TheBase
{
    public TheBase(int id)
    {

    }
}

public class TheArgument
{
    public int TheId { get; set; }
}

public class TheInheritor : TheBase
{
    public TheInheritor(TheArgument theArgument) : base(theArgument.TheId)
    {

    }
}
Run Code Online (Sandbox Code Playgroud)

有人现在构造一个这样的实例TheInheritor:

var theVar = new TheInheritor(null);
Run Code Online (Sandbox Code Playgroud)

我想不出一种方法可以null在base被调用之前检查(并抛出一个NullReferenceException).如果没有让TheBase构造函数接受TheArgument我的实例,我就无法看到如何进行这种理智检查.但是,如果TheArgument仅与之相关TheInheritor并且还有很多其他类继承自己TheBase呢?

有关如何解决这个问题的任何建议?

Jon*_*eet 44

你可以这样做:

public TheInheritor(TheArgument theArgument)
    : base(ConvertToId(theArgument))
{
}

private static int ConvertToId(TheArgument theArgument)
{
    if (theArgument == null)
    {
        throw new ArgumentNullException("theArgument");
    }
    return theArgument.Id;
}
Run Code Online (Sandbox Code Playgroud)

或者更一般地说,这样的事情:

public TheInheritor(TheArgument theArgument)
    : base(Preconditions.CheckNotNull(theArgument).Id)
{
}
Run Code Online (Sandbox Code Playgroud)

这里Preconditions是一个工具类的其他地方,像这样:

public static class Preconditions
{
    public static T CheckNotNull<T>(T value) where T : class
    {
        if (value == null)
        {
            throw new ArgumentNullException();
        }
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)

(当然,这会丢失参数名称,但如果需要,您也可以将其传递给.)


Jog*_*gge 12

从 C# 6.0 开始,您可以将空合并运算符与空条件运算符结合使用,如下所示:

public TheInheritor(TheArgument theArgument)
    : base(theArgument?.TheId ?? throw new ArgumentNullException(nameof(theArgument)))
{

}
Run Code Online (Sandbox Code Playgroud)