其他
编写或现代化 .NET 10/C# 14 代码时,用现代…
在编写新 C# 代码或审查旧代码现代化时,优先使用 C# 14/.NET 10 的语言级特性替代旧写法与库变通。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 35/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 39/100 ×0.15
适用场景
编写或现代化 .NET 10/C# 14特定
解决思路
- 以 C# 14 为目标,使用最新稳定语言特性,优先语言级构造而不是库层变通。
- 可读性优先于炫技:模式匹配与表达式体成员在恰当使用时提升可读性,深层嵌套模式匹配不要用。
- 尽可能使用值类型:优先 `record struct`、`Span<T>` 和栈分配,以减少 GC 压力。
- 默认不可变:使用 `record`、`readonly`、`init`、`required`,让非法状态不可表示。
- 主构造函数:用于 DI 注入并消除字段赋值,例如 `public class OrderService(IOrderRepo repo, TimeProvider clock) { }`。
- 集合表达式:所有集合类型用 `[]` 创建并支持展开,例如 `List<string> names = ["Alice", "Bob"];`、`int[] all = [..a, ..b, 99];`。
- Records:用于 DTO、值对象和不可变数据,例如 `public record CreateOrderRequest(string CustomerId, List<OrderItem> Items);`。
- `readonly record struct`:用于小型栈分配值类型,例如 `public readonly record struct Money(decimal Amount, string Currency);`。
- 模式匹配:使用 switch 表达式、列表模式、属性模式,例如 `order switch { { Total: > 1000 } => "Premium", _ => "Standard" };`。
- 列表模式:解构数组/列表,例如 `items switch { [] => "Empty", [var x] => $"One: {x}", [var f, .., var l] => $"{f}..{l}" };`。
- `Span<T>`:零分配切片,例如 `ReadOnlySpan<char> trimmed = input.Trim(); int.TryParse(trimmed[4..], out id);`。
- 原始字符串字面量:用于多行 SQL、JSON、XML,例如 `var sql = """ SELECT ... """;`,插值形式如 `$$""" {"id": "{{id}}"} """;`。
- `required` 成员:强制初始化,例如 `public required string ConnectionString { get; init; }`。
- `is` 模式 + 提取:进行 null/类型/属性检查,例如 `if (result is { IsSuccess: true, Value: var order }) { ... }`。
- 在属性访问器中使用 `field` 关键字访问自动生成的后备字段,无需手动声明。
- 用 `field` 在自动属性中做验证:`get => field; set => field = value?.Trim() ?? throw new ArgumentNullException(nameof(value));`。
- 用 `field` 做惰性初始化:`get => field ??= LoadProducts();`,无需手动 `Lazy<T>` 或后备字段。
- 用 `field` 实现变更通知:在 `INotifyPropertyChanged` 的 setter 中比较 `field == value`,更新 `field`,再触发 `PropertyChanged`,无需手写后备字段。
- 用 `field` 在如 `Price` 属性中做范围验证:`set => field = value >= 0 ? value : throw new ArgumentOutOfRangeException(nameof(value));`。
- C# 14 在静态类中使用 `extension` 块;与经典扩展方法不同,支持扩展属性和静态扩展成员,接收者在整个块中只声明一次。
- 用 `extension(Order order)` 块定义扩展属性/方法:`public decimal TotalWithTax => order.Total * 1.2m;`、`public bool IsHighValue => order.Total > 1000m;`、`public string ToSummary() => $"Order #{order.Id}: {order.Total:C} ({order.Items.Count} items)";`。
- 静态扩展成员用类型声明且无接收者实例:`extension(Order) { public static Order Empty => Order.Create("none", [], DateTimeOffset.MinValue); }`。
- 调用方像调用 `Order` 自身成员一样调用扩展成员,例如 `if (order.IsHighValue) { /* ... */ }`。
- 经典 `this` 参数扩展方法仍可用并可共存;需要属性或同一接收者的多个成员时用 extension 块。
- 当现代替代存在时,不要用过时模式:不要在手写后备字段能由 `field` 关键字替代时继续手写。
- 不要使用旧式集合初始化 `var list = new List<int>() { 1, 2, 3 };`;改用集合表达式。
- 不要用 Tuple 作为领域类型:`(string Name, decimal Price) product = ("Widget", 9.99m);` 改用 `public record Product(string Name, decimal Price);`。
- 不要过度模式匹配:避免 `if (order is { Customer: { Address: { Country: { Code: "US" } } } })` 这类深层嵌套;提取为清晰方法或顺序检查,如 `if (order.Customer.Address.Country.Code == "US")`。
- 类型不明显时不要用 `var`:例如 `var result = Process(order);` 应改为 `Result<Order> result = Process(order);`;类型明显时可用 `var`,如 `var orders = new List<Order>();`。
- DTO / API 契约:用 `record`(引用类型)。
- 小型值对象(2-3 个字段):用 `readonly record struct`。
- 带 DI 的服务:用主构造函数。
- 创建集合:用集合表达式 `[]`。
- 带验证的属性:用 `field` 关键字。
- 多行字符串(SQL、JSON):用原始字符串字面量 `"""`。
- 字符串/数组切片:用 `Span<T>`。
- 类型检查 + 提取:用 `is` / `switch` 模式匹配。
- 强制初始化:用 `required` 修饰符。
- 给外部类型添加方法:用扩展成员。
适用边界 · 注意事项
- 运行环境不支持 C# 14 / .NET 10 或编译器未升级时,不要强行使用 `field`、extension blocks 等新语法。
- 不要用深层嵌套模式匹配;可读性差时改用清晰方法或顺序检查。
- 当 `var` 推断类型不明显时不要用 `var`。