写在前面
本文是 .NET 新特性系列第三篇。.NET 7(2022-11)是非 LTS 版,但 C# 11 的表达力大幅提升:原始字符串、列表模式、required、generic math——这些让代码更简洁、更安全、更强大。
运行时方面,Dynamic PGO 默认开启,性能继续攀升。
一、版本概览
1
2
3
4
5
6
7
8
9
10
| .NET 7
发布:2022-11
支持:非 LTS(标准支持 18 个月)
C#:11
定位:表达力提升 + 性能打磨
特点:
✓ C# 11 语法大跃进(原始字符串、列表模式、required)
✓ Dynamic PGO 默认开启
✓ 限流、输出缓存等 ASP.NET Core 中间件
|
二、C# 11 语言特性(重点)
2.1 原始字符串字面量(raw string literals)⭐
三引号 """ 包裹,无需转义,跨多行,写正则/JSON/HTML 爽:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // 不用转义引号、反斜杠
var json = """
{
"name": "张三",
"regex": "\\d+"
}
""";
// 插值用多个 $($$ 表示字面 { 一个)
var json2 = $$"""
{
"id": {{userId}}
}
""";
// 写正则特别爽
var pattern = """\d{4}-\d{2}-\d{2}""";
|
2.2 列表模式(list patterns)⭐
匹配数组的结构和元素:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
| int[] arr = { 1, 2, 3 };
// 匹配固定结构
_ = arr is [1, 2, 3]; // true
_ = arr is [1, .., 3]; // true(.. 匹配中间任意个)
_ = arr is [_, _, _]; // 长度 3
// 解构
if (arr is [var first, .. var middle, var last])
{
// first=1, middle=[2], last=3
}
// switch
string Desc(int[] a) => a switch
{
[] => "空",
[single] => $"一个:{single}",
[a, b] => $"两个:{a},{b}",
[..] => "更多"
};
|
2.3 required 成员 ⭐
强制属性在构造时必须初始化:
1
2
3
4
5
6
7
8
9
10
11
| public class User
{
public required int Id { get; init; } // 必须初始化
public required string Name { get; init; } // 必须初始化
public string? Email { get; init; }
}
var u = new User(); // ❌ 编译错误:缺 Id、Name
var u2 = new User { Id = 1, Name = "x" }; // ✅ 必填项已提供
// 比 [Required](运行时验证)更强:编译期保证
|
2.4 generic math(静态抽象接口成员)⭐
接口可以有 static abstract 成员,让泛型数学运算成为可能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| // 以前:无法对泛型 T 做 T + T(没有运算符约束)
// C# 11:通过 static abstract 接口
// 内置:INumber<T>, IAdditionOperators<T,T,T> 等
static T Sum<T>(params T[] values) where T : INumber<T>
{
T sum = T.Zero;
foreach (var v in values) sum += v; // 泛型类型也能 + 运算了!
return sum;
}
Sum(1, 2, 3); // int: 6
Sum(1.5, 2.5); // double: 4.0
// 自己定义运算符接口
public interface IAddable<T> where T : IAddable<T>
{
static abstract T operator +(T a, T b);
}
|
1
2
3
4
| 意义:
以前泛型数学要写一堆重载 / 用 dynamic(性能差)
现在 INumber<T> 约束,一套代码处理所有数值类型
数值算法、向量运算极大受益
|
2.5 文件范围类型(file-scoped types)
类型只在当前文件可见:
1
2
3
4
5
| file class InternalHelper { } // 只在本 .cs 文件可见
// 解决:
// 同一程序集多个文件想定义同名辅助类
// 或想限制类型可见性到单文件
|
2.6 UTF-8 字符串字面量
1
2
3
4
| // u8 后缀:直接得到 UTF-8 字节(byte[]),不用 Encoding.GetBytes
byte[] bytes = "Hello"u8; // new byte[]{ 72, 101, ... }
// 网络协议、文件 IO 常需 UTF-8,省去运行时转换
|
2.7 其他
1
2
3
4
5
6
7
8
9
10
| // ref struct 放宽(可用作泛型参数,配合 Span)
// Span<char> 模式匹配
// checked 运算符(自定义 checked 版本)
// generic attributes(泛型特性)
public class MyAttr<T> : Attribute { }
// new() 在泛型约束
static T Create<T>() where T : new() => new T();
// nameof 作用域扩展
|
三、运行时与性能
3.1 Dynamic PGO 默认开启
1
2
3
4
5
| .NET 6 引入 PGO 雏形,.NET 7 默认开启并增强:
运行时收集热点方法的 profile(分支走向)
重新编译时基于真实数据优化(内联、分支预测)
实际应用性能提升 5~20%(无需改代码)
|
3.2 On-Stack Replacement (OSR)
1
2
3
4
| 方法正在执行中(长循环)也能从 tier 0 升级到 tier 1
以前:方法要重新调用才优化
现在:长时间运行的方法中途也能优化
利好长任务、循环密集代码
|
3.3 AOT 改进
1
2
| NativeAOT 实验性改进(.NET 8 才正式)
publish AOT 持续优化
|
3.4 其他
1
2
3
4
| ✓ JIT 改进(更多优化)
✓ 异步改进
✓ 反射性能(源生成器 代替)
✓ ARM64、LoongArch 支持
|
四、BCL 改进
4.1 CollectionsMarshal
1
2
3
4
5
| // 拿到 Dictionary 内部值的引用(避免拷贝、可原地改)
ref int val = ref CollectionsMarshal.GetValueRefOrAddDefault(dict, key, out bool exists);
val += 1; // 直接改字典内值,无拷贝
// 高性能字典操作
|
4.2 其他
1
2
3
4
5
| // Tar 类(读写 tar 归档)
// System.Text.Json:多态(polymorphic)部分支持
// Microsoft.Extensions.* 改进
// Random.Shared(线程安全随机)
// DateOnly/TimeOnly 增强
|
五、ASP.NET Core 7
5.1 速率限制中间件(Rate Limiter)
1
2
3
4
5
6
| builder.Services.AddRateLimiter(o =>
{
o.GlobalLimiter = PartitionedRateLimiter.Create<HttpContext, string>(...);
o.AddPolicy("per-ip", ctx => ...);
});
app.UseRateLimiter();
|
5.2 输出缓存(Output Cache)
1
2
3
4
| builder.Services.AddOutputCache();
app.UseOutputCache();
app.MapGet("/hot", () => GetData()).CacheOutput(t => t.Expire(TimeSpan.FromMinutes(1)));
|
5.3 其他
1
2
3
4
| ✓ MTLS(双向 TLS)支持
✓ HTTP/3
✓ OpenAPI 改进
✓ SignalR / Blazor 改进
|
六、升级建议
1
2
3
4
5
6
| .NET 7 已停止支持(2024-05),非 LTS 不适合长期生产
→ 升级到 8(LTS)
但 C# 11 特性(原始字符串、列表模式、required、generic math):
→ 项目 ≥ 7 即可用,强烈推荐
→ 原始字符串 + 列表模式 + required 是日常高频特性
|
七、小结
.NET 7 是表达力提升的一版:
- C# 11:原始字符串(""")、列表模式、required、generic math(static abstract 接口)、file 类型、UTF-8 字面量
- 运行时:Dynamic PGO 默认开启、OSR
- BCL:CollectionsMarshal、Tar、Random.Shared
- ASP.NET Core:限流中间件、输出缓存、MTLS、HTTP/3
- 定位:非 LTS,但 C# 11 特性极有价值
下一篇讲 .NET 8(C# 12):主构造函数、集合表达式、NativeAOT 正式——成熟的一代 LTS。