之前主要使用类中的私有字段并将所需的对象传递到构造函数中,我正在尝试使用公共属性以及 C# 版本 11 中引入的 required 修饰符关键字。
这背后的驱动因素之一是,在我设置依赖注入的地方,我的一些类有五六个需要传入的对象,并且我发现使用对象初始化程序而不是构造函数初始化时代码更容易阅读,如果相同类型的对象以错误的顺序提供,则可能会被忽视(是的,我知道我可以使用构造函数初始化指定参数名称,但代码变得非常冗长,非常快,这正是我的目的)我试图避免)。
我尝试使用无参数构造函数对构造函数中的这些属性执行空检查,如下所示...
public class SomeClass
{
public required Person Person { get;init; }
public SomeClass()
{
ArgumentNullException.ThrowIfNull(this.Person);
}
}
但是当我实例化该类时
var foo = new SomeClass()
{
Person = new Person()
};
我从构造函数中的空检查中收到异常,因此很明显,构造函数是在设置属性之前调用的,这是有道理的,但我现在想,如果我必须对属性执行空检查,应该我避开所需的属性并以其他方式处理不太美观的对象初始化代码?
我可以实现 IValidatableObject,但这感觉就像一种令人讨厌的代码味道,必须调用一个方法来处理我本来可以通过构造函数初始化来处理的事情。
您可以从自动实现的属性切换到带有支持字段的属性:
public class SomeClass
{
private readonly Person _person;
public required Person Person
{
get => _person;
[MemberNotNull(nameof(_person))]
init
{
ArgumentNullException.ThrowIfNull(value);
_person = value;
}
}
}
构造函数在 init 表达式之前调用(通常与对象初始化器一样),因此属性的实际值将在构造函数中执行检查后设置。查看反编译@sharplab.io.