C#如何使用required members C# 11 required关键字用法

来源:这里教程网 时间:2026-02-21 17:37:33 作者:

C# 11 引入的 required members(必需成员)机制,主要是为了解决对象初始化时某些字段或属性“必须赋值但又不想写构造函数”的问题。它不依赖构造函数参数,而是通过

required
关键字标记字段/属性,在编译期强制要求在对象初始化器中设置——没赋值就报错。

required 成员的基本用法

只需在类或结构体的字段或自动属性前加

required
修饰符即可。该成员必须在对象初始化器(
new TypeName { ... }
)中显式赋值。

仅支持实例字段和自动属性(不支持手动实现 get/set 的属性) 不能用于
static
const
init
(init-only 属性本身可被标记为 required)、
readonly
字段(除非同时用
init
支持继承:基类的 required 成员,派生类初始化时也必须提供

示例:

public class Person
{
    public required string Name { get; set; }
    public required int Age { get; set; }
    public string? Email { get; set; } // 非 required,可选
}
<p>// ✅ 正确:Name 和 Age 都在初始化器中赋值
var p = new Person { Name = "Alice", Age = 30 };</p><p>// ❌ 编译错误:缺少 required 成员 Age
// var p2 = new Person { Name = "Bob" }; // 报错 CS8852

与构造函数和 init-only 属性配合使用

required 成员可和

init
属性共存,适合构建不可变但需灵活初始化的对象。

required init
属性:只能在初始化器中设一次,之后不可改
仍允许无参构造函数存在,但调用后若未用初始化器赋值 required 成员,编译失败 也可搭配自定义构造函数,但构造函数内部赋值不会绕过 required 检查(即:仍需在初始化器中出现)

示例:

public class Product
{
    public required init string Sku { get; set; }
    public required init decimal Price { get; set; }
    public string? Description { get; set; }
}
<p>// ✅ 合法:init 属性 + required 保证初始化完整性
var prod = new Product { Sku = "P123", Price = 29.99m };</p><p>// ❌ 错误:Sku 和 Price 是 required init,不能省略
// var bad = new Product(); // 编译失败

序列化与反射注意事项

required 成员本身是编译器特性,不影响运行时行为,但会影响部分框架行为:

JSON 序列化(如 System.Text.Json)默认不感知
required
,需手动配置验证逻辑或结合
[Required]
(DataAnnotations)
反射中无法直接判断某属性是否被标记为
required
(无对应元数据),这是编译期检查,非运行时属性
源生成器(Source Generators)可读取语法树识别
required
,适合构建验证或文档工具

常见误区提醒

别把

required
当作运行时约束或数据验证手段:

它不等于
[Required]
(DataAnnotations),后者用于模型绑定和验证,运行时生效
它不能替代构造函数逻辑(比如校验 Age > 0),只是确保字段被“写”了,不管写的是不是有效值 如果用了 record 或 record struct,
required
依然适用,但要注意 primary constructor 参数和 required 属性的分工

基本上就这些。required members 是轻量级、编译期友好的初始化保障机制,适合简化 DTO、配置类、API 请求模型等场景,不复杂但容易忽略细节。

相关推荐