C# 9新特性:record类型、模式匹配与init访问器详解
C# 9引入了record类型以简化数据比较,扩展了模式匹配能力,并新增init访问器实现更优雅的对象初始化限制。
一、record类型(记录类型)
record是一种特殊的引用类型,与 class 类似,但专注于数据值的表达。在传统的类中,== 运算符默认比较的是两个对象的引用(即内存地址是否相同)。而在数据处理场景中,我们通常希望基于对象内部的属性值来判断两个实例是否“相等”。
第1步:声明与定义
将原有的类声明改为 record,编译器会自动生成基于每个成员的值相等的逻辑,无需手动重写 Equals 和 GetHashCode 方法。
public record Cat
{
public string Nick { get; set; }
public string Name { get; set; }
public int Age { get; set; }
}
第2步:值相等性测试
创建两个内容完全相同的实例时,使用 == 直接比较即可:
// pet1 和 pet2 描述同一只猫
var pet1 = new Cat { Nick = "松子", Name = "Jack", Age = 1 };
var pet2 = new Cat { Nick = "松子", Name = "Jack", Age = 1 };
Console.WriteLine("同一只?" + (pet1 == pet2)); // 输出:True
这极大简化了类似用户验证等需要比对数据的业务逻辑。
二、模式匹配(Pattern Matching)增强
第1步:改进的 switch case 语法
过去 switch 只能判断常量或精确值。C# 9 允许在 case 中使用逻辑运算,如 and、or 和范围比较:
switch (考试成绩)
{
case >= 0 and <= 30: Console.WriteLine("不及格"); break;
case >= 80 and <= 100: Console.WriteLine("优秀"); break;
}
第2步:成员属性模式匹配
不仅限于值,还可以深入对象的内部属性进行模式检查。例如根据订单数量(Qty)判断收益情况:
switch (od)
{
case { Qty: > 1000f }: Console.WriteLine("发财了"); break;
case { Qty: > 500f }: Console.WriteLine("大单"); break;
}
这里 { Qty: ... } 表示匹配一个 Order 类型的对象,且其内部分量大于指定数值。多属性匹配时使用逗号分隔,默认为 AND 关系:case { Qty: > 100f, Company: not null }。
第3步:is 运算符的模式匹配
在 if 判断中直接使用 is 提取并转换类型,一步到位:
object n = 5000000L;
if (n is long x)
{
Console.WriteLine($"长整型,值为:{x}");
}
第4步:switch 表达式
如果只需要根据模式返回不同结果,可以使用轻量级的 switch 表达式:
string message = od switch
{
{ Qty: > 1000f } => "发财了",
{ Qty: > 500f } => "年度大订单",
_ => "未知"
};
注意:末尾下划线 _ 起到 default 的作用,处理未匹配的情况。
三、init 属性的单向初始化
init 访问器用于解决仅读属性(只有 get)在外部赋值的难题。它允许属性在对象初始化期间被修改,一旦初始化完成则变为只读。
第1步:定义 init 属性
在属性声明中使用 init 替代 set:
public class Dog
{
public int No { get; init; }
public string Name { get; init; }
public int Age { get; init; }
}
第2步:对象初始化
在创建新对象时通过属性初始化器赋值,不再需要编写冗长的构造函数:
Dog x = new Dog
{
No = 100,
Name = "吉吉",
Age = 4
};
第3步:尝试修改(预期失败)
对象初始化完成后,任何试图修改这些属性的操作都会导致编译错误:

x.Name = "冬冬"; // 报错:无法为只读字段或参数分配值
综上,以上就是关于C# 9中record类型、模式匹配与init属性使用的详细内容,更多关于C# 9新特性的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













