当前位置: 首页 > news >正文

【.NET新特性·第6篇】C# 13 新特性全解:10 个改变你编码方式的特性

C# 13 带来了 params 集合、新 Lock 类型、ref struct 突破等 11 个新特性

版本定位

适用版本:.NET 9 | C# 13 前置知识:C# 12 基础

背景

C# 13 是继 C# 12 之后的又一次重要更新。这次更新的重点是泛型系统的突破性能优化。ref struct 可以实现接口、泛型支持 ref struct 类型参数,这些改变让 C# 的类型系统更加强大。

C# 13 新特性一览

特性简述实用性
params 集合params支持Span<T>IEnumerable<T>⭐⭐⭐⭐⭐
新 Lock 类型System.Threading.Lock替代Monitor⭐⭐⭐⭐⭐
\e 转义序列新的转义字符⭐⭐⭐
method group 自然类型方法组推断改进⭐⭐⭐
ref struct 实现接口ref struct 可以实现接口⭐⭐⭐⭐
allows ref struct泛型支持 ref struct⭐⭐⭐⭐
partial 属性属性和索引器支持 partial⭐⭐⭐⭐
overload 优先级库作者可以指定重载优先级⭐⭐⭐
ref locals in iterators迭代器中支持 ref 局部变量⭐⭐⭐
field keyword(预览)字段关键字预览⭐⭐⭐⭐
隐式索引器访问对象初始化器中使用[^]语法⭐⭐⭐⭐

特性详解

1. params 集合

之前的做法params只支持数组

// C# 12 及之前 void PrintAll(params string[] items) { foreach (var item in items) { Console.WriteLine(item); } } PrintAll("a", "b", "c"); // OK // PrintAll([1, 2, 3]); // 编译错误

C# 13 的做法params支持所有集合类型

// C# 13 void PrintAll(params string[] items) { /* ... */ } void PrintAll(params List<string> items) { /* ... */ } void PrintAll(params ReadOnlySpan<string> items) { /* ... */ } void PrintAll(params IEnumerable<string> items) { /* ... */ } // 现在可以用集合表达式 PrintAll(["a", "b", "c"]); // OK,适用于所有重载

性能优势

  • Span<T>避免堆分配

  • 编译器优化,减少内存拷贝

2. 新 Lock 类型

之前的做法:使用Monitorlock语句

// C# 12 及之前 private readonly object _lock = new(); void DoWork() { lock (_lock) { // 临界区 } } // 或者显式使用 Monitor void DoWorkExplicit() { Monitor.Enter(_lock); try { // 临界区 } finally { Monitor.Exit(_lock); } }

C# 13 的做法:使用System.Threading.Lock

// C# 13 private readonly Lock _lock = new(); void DoWork() { lock (_lock) // 自动使用新的 Lock 类型 { // 临界区 } } // 或者显式使用 void DoWorkExplicit() { using var scope = _lock.EnterScope(); // 临界区 }

优势

  • 更好的性能

  • 更清晰的语义

  • 防止 lock 对象被错误转换

3. \e 转义序列

// C# 12 及之前 char esc = '\x1b'; // 十六进制 char esc2 = ''; // Unicode // C# 13 char esc = '\e'; // 新的转义序列

4. method group 自然类型

// C# 13 改进了方法组的类型推断 void Process<T>(Action<T> action) { /* ... */ } // C# 12 可能需要显式类型 Process<int>(x => Console.WriteLine(x)); // C# 13 可以推断类型 Process(x => Console.WriteLine(x)); // 编译器推断 T 为 int

5. ref struct 实现接口

之前的做法:ref struct 不能实现接口

// C# 12 及之前 ref struct MyStruct { public int Value; } // 不能实现接口 // interface IDisposable { void Dispose(); } // ref struct MyStruct : IDisposable { ... } // 编译错误

C# 13 的做法:ref struct 可以实现接口

// C# 13 ref struct MyStruct : IDisposable { public int Value; public void Dispose() { // 清理资源 } } // 使用 void Process<T>(T item) where T : IDisposable { item.Dispose(); } var myStruct = new MyStruct { Value = 42 }; Process(myStruct); // OK

6. allows ref struct

之前的做法:泛型不支持 ref struct

// C# 12 及之前 void Process<T>(T item) where T : struct { // 不能使用 ref struct } // Process<MyRefStruct>(myStruct); // 编译错误

C# 13 的做法:泛型支持 ref struct

// C# 13 void Process<T>(T item) where T : allows ref struct { // 可以使用 ref struct } Process<MyRefStruct>(myStruct); // OK

7. partial 属性和索引器

// C# 13 partial class MyClass { partial int Count { get; set; } partial int this[int index] { get; set; } } // 源生成器可以实现这些成员 partial class MyClass { partial int Count => _internalCount; partial int this[int index] => _internalArray[index]; }

8. overload 优先级

// 库作者可以指定重载优先级 public class MyService { [OverloadResolutionPriority(1)] public void Process(int value) { /* 高优先级 */ } [OverloadResolutionPriority(0)] public void Process(object value) { /* 低优先级 */ } } // 调用时优先选择高优先级的重载 var service = new MyService(); service.Process(42); // 调用 Process(int),而不是 Process(object)

9. ref locals in iterators

// C# 13 IEnumerable<int> Process(Span<int> data) { ref int first = ref data[0]; first = 100; // OK yield return first; }

10. field keyword(预览)

// C# 13 预览 public class Person { public string Name { get => field; set => field = value?.Trim() ?? string.Empty; } }

11. 隐式索引器访问(Implicit indexer access from object initializers)

之前的做法:对象初始化器中不能使用索引器语法

// C# 12 及之前 var list = new List<string>(); list.Add("a"); list.Add("b"); list[list.Count] = "hello"; // 必须在对象初始化器外赋值 // 或者使用集合初始化器 var dict = new Dictionary<string, int> { ["key1"] = 1, ["key2"] = 2 }; // 但不能在对象初始化器中使用索引器

C# 13 的做法:对象初始化器中支持隐式索引器访问

// C# 13 // 数组 var array = new string[10]; array[^1] = "last element"; // 等价于 array[array.Length - 1] // 在对象初始化器中使用 var list = new List<string> { [^1] = "hello" }; // 与属性初始化结合 var grid = new Grid { [0, 0] = "A1", [0, 1] = "A2", [1, 0] = "B1" };

使用场景

// 集合初始化 var stack = new Stack<int> { [^1] = 10, // 压栈操作的语法糖 [^1] = 20 }; // 矩阵初始化 var matrix = new Matrix(3, 3); matrix[^1, ^1] = 1.0; // 设置右下角元素 // 字符串缓冲区 var buffer = new char[100]; buffer[^1] = '\0'; // 设置结束符

实战场景

params 集合适合的场景

// 日志方法 void Log(params string[] messages) { foreach (var msg in messages) Console.WriteLine($"[{DateTime.Now}] {msg}"); } // 现在可以用集合表达式 Log(["Error", "Warning", "Info"]);

新 Lock 类型适合的场景

// 缓存管理 public class Cache<T> { private readonly Lock _lock = new(); private readonly Dictionary<string, T> _cache = new(); public T GetOrAdd(string key, Func<T> factory) { lock (_lock) { if (!_cache.TryGetValue(key, out var value)) { value = factory(); _cache[key] = value; } return value; } } }

ref struct 接口适合的场景

// 高性能解析器 ref struct JsonParser : IDisposable { private ReadOnlySpan<char> _json; public JsonParser(ReadOnlySpan<char> json) { _json = json; } public void Dispose() { // 清理资源 } } // 可以与泛型方法配合使用 void Process<T>(T parser) where T : IDisposable { using (parser) { // 处理数据 } }

隐式索引器访问适合的场景

// 游戏开发中的网格初始化 var board = new ChessBoard { [0, 0] = new Rook(Color.White), [0, 1] = new Knight(Color.White), [7, 0] = new Rook(Color.Black), [7, 1] = new Knight(Color.Black) }; // 配置文件解析 var config = new Config { ["database.host"] = "localhost", ["database.port"] = "5432", ["cache.enabled"] = "true" }; // 数据结构初始化 var ringBuffer = new RingBuffer<int>(100); ringBuffer[^1] = 42; // 直接设置最后一个位置

迁移建议

自动迁移

C# 13 特性大部分向后兼容:

<PropertyGroup> <LangVersion>13</LangVersion> </PropertyGroup>

需要注意的 breaking changes

  1. Lock 类型:如果代码检查lock对象的类型,可能会受影响

  2. method group:类型推断可能推断出不同的类型

  3. overload 优先级:可能改变现有代码的重载选择

  4. 隐式索引器访问:如果代码中已有类似语法,可能会产生歧义

一句话总结

C# 13 是泛型系统的突破,ref struct 实现接口和 allows ref struct 让 C# 的类型系统更加强大。


官方文档

  • What's new in C# 13

  • params collections

  • New lock type

  • ref struct interfaces


📦示例代码:.NET 新特性巡礼全系列配套示例代码(含 dotnet 8/9/10)

  • GitHub:GitHub - LadyKiller1025/dotnet-feature-tour-demos: .NET Feature Tour - Code Demos (.NET 8/9/10) · GitHub

  • Gitee:https://gitee.com/qakjhzx/dotnet-feature-tour-demos

💬 欢迎点赞、收藏、转发,你的支持是我持续创作的动力!

http://www.jsqmd.com/news/1092985/

相关文章:

  • 从零逆向sig3签名算法:纯算分析实战与移动应用安全机制解析
  • 我发现......Data Agent 正在续写 GPS 导航的故事
  • 《深入理解计算机系统》CSAPP八大实验通关指南与实战解析
  • 终极解放!U校园智能刷课工具AutoUnipus:2分钟完成网课必修题
  • 凑微分,幂等公式
  • 【单片机毕业设计】基于 STM32 的老人跌倒与环境监测报警装置设计,基于单片机的多传感器安全监护系统设计与实现(013501)
  • TAS54x4A评估模块实战:从硬件连接到软件调试的完整指南
  • 大文件分片上传:从原理到实战,解决Web开发中的传输难题
  • 按照这个方法真的领到了8元
  • GeoTools 多模块依赖最佳实践:一次 OrderedAxisAuthorityFactory 初始化失败的深度复盘
  • 【大模型原理与微调实战02】为什么需要Transformer?深度剖析RNN/LSTM核心缺陷
  • PROFINET 工业无线 IWLAN 全解析(上)
  • Nacos 注解全解析:7 个核心注解 + 5 个生产踩坑清单(2026 实测)
  • 虚拟判断者与真实创造者——所属技术领域的技术人员与发明人的对比分析
  • petpetgo项目
  • 凑微分 sinx和cosx的转换
  • Sesame-TK:面向支付宝生态的模块化自动化解决方案
  • Java代码使用ssh来连接服务器+LibreOffice命令转换文件doc-docx
  • 英语启蒙分级体系完善的app推荐,对标国内小学教材零基础友好
  • go: Deadline Pattern
  • HarmonyOS 实战|中式美食食材大全页:分类联动、网格稳定高度与食材检索入口设计
  • 清宫后多久出门不怕风?分阶段防风与科学修护指
  • 论文阅读笔记 | Thinking in Frames: How Visual Context and Test-Time Scaling Empower Video Reasoning
  • Upstage AI发现了生物医学大模型最隐蔽的致命缺陷
  • 万字干货|2026 Go 后端通关学习路线,从底层原理到微服务面试全覆盖(附 Code Review 规范 + 线上故障排查方案)
  • 泛微ECOLOGY9流程主明细行弹窗添加子明细的实现
  • 解除labelstdio数据标注一次上传图片数量限制的方法
  • TAS2564评估板实战:从数字功放原理到立体声系统集成
  • 一人创业时,内容、开发、客户跟进分别适合用哪些AI工具辅助
  • AI赋能UI自动化测试:从智能自愈到自主测试的演进之路