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

16次阅读

C# 11 的 required members 机制通过 required 关键字在编译期强制对象初始化器中赋值指定字段或自动属性,不依赖构造函数,支持继承和 init 属性,但非运行时约束,不影响序列化与反射。

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

C# 11 引入的 required members(必需成员)机制,主要是为了解决对象初始化时某些字段或属性“必须赋值但又不想写构造函数”的问题。它不依赖构造函数参数,而是通过 required 关键字标记字段/属性,在编译期强制要求在对象初始化器中设置——没赋值就报错。

required 成员的基本用法

只需在类或结构体的字段或自动属性前加 required 修饰符即可。该成员必须在对象初始化器(new TypeName { ... })中显式赋值。

  • 仅支持实例字段和自动属性(不支持手动实现 get/set 的属性)
  • 不能用于 Staticconstinit(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,可选 } 

// ✅ 正确:Name 和 Age 都在初始化器中赋值 var p = new Person { Name = "Alice", Age = 30 };

// ❌ 编译错误:缺少 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; } } 

// ✅ 合法:init 属性 + required 保证初始化完整性 var prod = new Product { Sku = "P123", Price = 29.99m };

// ❌ 错误: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 Structrequired 依然适用,但要注意 primary constructor 参数和 required 属性的分工

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

text=ZqhQzanResources