确保类中所需的属性不为 null

Ensuring required properties in a class are not null

提问人:Bryan 提问时间:11/17/2023 更新时间:11/17/2023 访问量:33

问:

我以前主要在我的类中使用私有字段并将必需的对象传递到构造函数中,我正在尝试使用带有 C# 版本 11 中引入的 required modifier 关键字的公共属性。

这背后的驱动因素之一是,在我设置依赖注入的地方,我的一些类有五六个需要传入的必需对象,我发现在使用对象初始化器而不是构造函数初始化时,代码更容易阅读,如果以错误的顺序提供相同类型的对象,它们可能会被忽视(是的,我知道我可以使用构造函数指定参数名称初始化,但代码变得非常冗长,非常快,这正是我试图避免的)。

我尝试使用无参数构造函数对构造函数中的这些属性执行空检查,如下所示......

public class SomeClass
{
    public required Person Person { get;init; }

    public SomeClass()
    {
        ArgumentNullException.ThrowIfNull(this.Person);
    }
}

但是当我实例化类时

var foo = new SomeClass()
{
    Person = new Person()
};

我从构造函数中的空检查中收到异常,因此很明显,构造函数是在设置属性之前调用的,这是有道理的,但是我现在在想,如果我必须对属性执行空检查,我是否应该避开所需的属性并以其他方式处理不太美观的对象初始化代码?

我可以实现 IValidatableObject,但这感觉就像一个令人讨厌的代码气味,必须为我将使用构造函数初始化处理的东西调用方法。

C# 属性 构造函数注入 null-check

评论


答:

1赞 Guru Stron 11/17/2023 #1

您可以从自动实现的属性切换到带有后备字段的属性:

public class SomeClass
{
    private readonly Person _person; 

    public required Person Person
    {
        get => _person;
        [MemberNotNull(nameof(_person))]
        init
        {
            ArgumentNullException.ThrowIfNull(value);
            _person = value;
        }
    }
}

构造函数在初始化表达式之前调用(与一般的对象初始值设定项一样),因此属性的实际值将在构造函数中执行检查后设置。查看反编译@sharplab.io