required 修饰符(C# 参考)
required
修饰符表示其所应用的字段或属性必须由所有构造函数或使用对象初始值设定项进行初始化。 用于初始化该类型新实例的任何表达式都必须初始化所有必需的成员。 required
修饰符从 C# 11 开始可用。 required
修饰符使开发人员能够创建必须正确初始化属性或字段的类型,但仍允许使用对象初始值设定项进行初始化。 多个规则可确保此行为:
required
修饰符可应用于在struct
中声明的字段和属性,以及class
类型,包括record
和record struct
类型。required
修饰符不能应用于interface
的成员。- 显式接口实现不能标记为
required
。 不能在对象初始值设定项中设置它们。 - 必须初始化必需的成员,但可将其初始化为
null
。 如果该类型是不可为 null 的引用类型,则在将成员初始化为null
时编译器会发出警告。 如果成员根本没有初始化,编译器会发出错误。 - 必需的成员必须至少与其包含类型一样可见。 例如,
public
类不能包含protected
的required
字段。 此外,必需的属性必须具有至少与其包含类型一样可见的资源库(set
或init
访问器)。 不可访问的成员不能由创建实例的代码设置。 - 派生类不能隐藏在基类中声明的
required
成员。 隐藏必需的成员可防止调用方为其使用对象初始值设定项。 此外,重写必需属性的派生类型必须包含required
修饰符。 派生类型无法删除required
状态。 派生类型可以在重写属性时添加required
修饰符。 - 当类型参数包含
new()
约束时,不能将具有任何required
成员的类型用作类型参数。 编译器无法强制在泛型代码中初始化所有必需的成员。 - 不允许对记录上的位置参数声明使用
required
修饰符。 可以为包含required
修饰符的位置属性添加显式声明。
某些类型(如位置记录)使用主构造函数初始化位置属性。 如果其中任一属性包括 required
修饰符,则主构造函数将添加 SetsRequiredMembers
属性。 这表示主构造函数初始化所有必需的成员。 可以使用 System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute 特性编写自己的构造函数。 但是,编译器不会验证这些构造函数是否初始化所有必需的成员。 该特性会转而向编译器断言构造函数会初始化所有必需的成员。 SetsRequiredMembers
特性会将这些规则添加到构造函数:
- 链接到另一个使用
SetsRequiredMembers
属性批注的构造函数(this()
或base()
)的构造函数还必须包含SetsRequiredMembers
属性。 这可确保调用方能够正确使用所有适当的构造函数。 - 如果任何成员为
required
,则为record
类型生成的复制构造函数应用SetsRequiredMembers
属性。
警告
SetsRequiredMembers
禁用编译器检查所有 required
成员在创建对象时是否已初始化。 请谨慎使用。
下面的代码显示了对 FirstName
和 LastName
属性使用 required
修饰符的类层次结构:
public class Person
{
public Person() { }
[SetsRequiredMembers]
public Person(string firstName, string lastName) =>
(FirstName, LastName) = (firstName, lastName);
public required string FirstName { get; init; }
public required string LastName { get; init; }
public int? Age { get; set; }
}
public class Student : Person
{
public Student() : base()
{
}
[SetsRequiredMembers]
public Student(string firstName, string lastName) :
base(firstName, lastName)
{
}
public double GPA { get; set; }
}
有关所需成员的详细信息,请参阅 C#11 - 必需成员功能规范。