.NET 新特性(二):.NET 6(C# 10)首个统一 LTS

写在前面

本文是 .NET 新特性系列第二篇。.NET 6(2021-11)是统一平台的首个 LTS——.NET 5 完成了品牌统一,.NET 6 让它稳定可生产,成为现代 .NET 真正的起点。

C# 10 重点是减少样板代码(全局 using、文件命名空间),运行时性能继续提升,ASP.NET Core 引入 Minimal APIs 改变了 API 开发方式。


一、版本概览

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
.NET 6
  发布:2021-11
  支持:LTS(3 年)
  C#:10
  定位:首个统一 LTS,现代 .NET 生产起点

  相比 .NET 5:
    ✓ LTS(企业敢用)
    ✓ 性能进一步打磨
    ✓ Minimal APIs(API 开发革命)
    ✓ .NET MAUI(跨平台 UI)正式版

二、C# 10 语言特性

2.1 全局 using(global using)

每个文件不用重复写 using,定义一次全项目生效:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// 方式一:代码声明(放 GlobalUsings.cs)
global using System.Collections.Generic;
global using System.Linq;

// 方式二:.csproj 开启隐式 using
// <ImplicitUsings>enable</ImplicitUsings>
// 自动启用 System / System.Collections.Generic / System.Linq 等一组

// 之后所有文件不用再写这些 using
public class Service
{
    public List<int> Get() => new();   // 不用 using System.Collections.Generic
}

2.2 文件范围命名空间(file-scoped namespace)

整个文件一个命名空间时,少一层缩进:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
// 旧:块作用域,多一层缩进
namespace MyApp.Services
{
    public class UserService { }
}

// 新(C# 10):分号结尾,少一层缩进
namespace MyApp.Services;

public class UserService { }

2.3 record struct(值类型记录)

C# 9 的 record 是引用类型。C# 10 增加 record struct(值类型):

1
2
3
4
5
6
7
8
9
// record(引用类型)
public record Point(double X, double Y);

// record struct(值类型,栈分配,无 GC)
public readonly record struct Point(double X, double Y);

// 都有 record 特性:值相等、解构、with、ToString
var p1 = new Point(1, 2);
var p2 = p1 with { X = 10 };   // 非破坏性修改

2.4 结构体改进

1
2
3
4
5
6
7
8
// 结构体可有无参构造 + 字段初始化
public struct Temperature
{
    public double Value { get; init; } = 25.0;
    public Temperature() { }
}

// struct 也能用 with 表达式(C# 10)

2.5 const 插值字符串

1
2
3
const string App = "MyApp";
const string Version = "1.0";
const string FullName = $"{App} {Version}";   // C# 10:const 插值(组成部分都是常量时)

2.6 Lambda 改进

1
2
3
4
5
6
7
8
// 自然类型:编译器推断委托类型
var add = (int a, int b) => a + b;          // 自动 Func<int,int,int>

// 显式声明返回类型
var parse = object (bool b) => b ? (object)1 : "x";

// Lambda 可加特性
var handler = [Description("处理")] (string s) => Process(s);

2.7 CallerArgumentExpression

参数为空时自动用另一个参数的表达式作异常信息:

1
2
3
4
5
6
7
public static void ThrowIfNull(object? arg,
    [CallerArgumentExpression(nameof(arg))] string? name = null)
{
    if (arg is null) throw new ArgumentNullException(name);
}

ThrowIfNull(user);   // 抛:ArgumentNullException: user(自动带参数名)

2.8 其他

1
2
3
4
5
6
7
8
// record 的 ToString 可 sealed(防派生覆盖)
public record Derived(string Name) : Base(Name)
{
    public sealed override string ToString() => Name;
}

// 解构在 using 中、属性模式改进(嵌套简写)
static bool IsCenter(Point p) => p is { X: 0, Y: 0 };

三、运行时与性能

3.1 分层编译 + PGO 雏形

1
2
3
4
5
6
7
分层编译稳定:
  方法首次执行:快速低优化编译(tier 0)
  成为热点:重新高度优化(tier 1)
  兼顾启动速度与峰值性能

PGO(Profile-Guided Optimization)雏形:
  基于运行 profile 优化热点(.NET 6 引入,后续增强)

3.2 热重载(Hot Reload)

1
2
3
4
改代码不重启:
  ✓ ASP.NET Core 改控制器,浏览器刷新生效
  ✓ Blazor 热重载
  ✓ MAUI

3.3 Source Generator 成熟

1
2
3
4
5
编译时生成代码(代替反射):
  ✓ 编译期生成,无运行时反射开销
  ✓ 类型安全
  ✓ AOT 友好
  应用:JSON 源生成、日志、配置绑定

3.4 其他性能

1
2
3
4
✓ Server GC 优化(多核)
✓ JIT 改进(内联、向量化)
✓ List<T> / Dictionary 优化
✓ async state machine 开销降低

四、BCL 新增

4.1 DateOnly / TimeOnly

1
2
3
4
5
DateOnly date = DateOnly.FromDateTime(DateTime.Now);   // 2026-05-23
TimeOnly time = TimeOnly.FromDateTime(DateTime.Now);   // 14:30:00

// 解决 DateTime 既表日期又表时间的混乱
// 生日用 DateOnly,打卡用 TimeOnly

4.2 PriorityQueue

1
2
3
4
var pq = new PriorityQueue<string, int>();
pq.Enqueue("普通", 1);
pq.Enqueue("紧急", 10);
pq.Dequeue();   // "紧急"(优先级最高)

4.3 PeriodicTimer

1
2
3
var timer = new PeriodicTimer(TimeSpan.FromSeconds(1));
while (await timer.WaitForNextTickAsync())
    DoWork();   // 每秒一次,异步友好

4.4 ThrowIf 辅助方法

1
2
3
4
ArgumentNullException.ThrowIfNull(arg);
ArgumentNullException.ThrowIfNullOrEmpty(str);
ArgumentOutOfRangeException.ThrowIfNegative(n);
// 内部用 CallerArgumentExpression,自动带参数名

4.5 其他

1
2
Channel<int> ch = Channel.CreateBounded<int>(100);   // Channel 稳定
var chunks = Enumerable.Range(0, 10).Chunk(3);        // 分块

五、ASP.NET Core 6

5.1 Minimal APIs

1
2
3
4
5
6
7
8
9
// Program.cs 几行写完 API,不用 Controller
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello");
app.MapGet("/users/{id}", (int id, IUserService svc) => svc.Get(id));
app.MapPost("/users", (User u) => Create(u));

app.Run();

5.2 其他

1
2
3
4
✓ 热重载(开发体验)
✓ Blazor 大幅改进
✓ .NET MAUI(跨平台 UI)
✓ 性能(HTTP/2、I/O)

六、升级建议

1
2
3
4
5
6
7
还在 .NET Core 3.1 / 5?
  → 升级到 6+(3.1 已停止支持)
  → 用 upgrade-assistant(微软迁移工具)

新项目:
  → 直接从 LTS(6/8/10)开始
  → 开启 ImplicitUsings、Nullable、分层编译

七、小结

.NET 6 是现代 .NET 的生产基石:

  • C# 10:全局 using、文件命名空间、record struct、结构体改进、lambda 自然类型、CallerArgumentExpression
  • 运行时:分层编译、PGO 雏形、热重载、Source Generator 成熟
  • BCL:DateOnly/TimeOnly、PriorityQueue、PeriodicTimer、ThrowIf 辅助
  • ASP.NET Core:Minimal APIs、热重载、Blazor、MAUI
  • 定位:首个统一 LTS,企业生产首选起点

下一篇讲 .NET 7(C# 11):原始字符串、列表模式、required、generic math。