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

📅 2026/6/30 1:30:12
【.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支持SpanT、IEnumerableT等⭐⭐⭐⭐⭐新 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 Liststring items) { /* ... */ } void PrintAll(params ReadOnlySpanstring items) { /* ... */ } void PrintAll(params IEnumerablestring items) { /* ... */ } // 现在可以用集合表达式 PrintAll([a, b, c]); // OK适用于所有重载性能优势SpanT避免堆分配编译器优化减少内存拷贝2. 新 Lock 类型之前的做法使用Monitor或lock语句// 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 ProcessT(ActionT action) { /* ... */ } // C# 12 可能需要显式类型 Processint(x Console.WriteLine(x)); // C# 13 可以推断类型 Process(x Console.WriteLine(x)); // 编译器推断 T 为 int5. 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 ProcessT(T item) where T : IDisposable { item.Dispose(); } var myStruct new MyStruct { Value 42 }; Process(myStruct); // OK6. allows ref struct之前的做法泛型不支持 ref struct// C# 12 及之前 void ProcessT(T item) where T : struct { // 不能使用 ref struct } // ProcessMyRefStruct(myStruct); // 编译错误C# 13 的做法泛型支持 ref struct// C# 13 void ProcessT(T item) where T : allows ref struct { // 可以使用 ref struct } ProcessMyRefStruct(myStruct); // OK7. 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 IEnumerableint Process(Spanint 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 Liststring(); list.Add(a); list.Add(b); list[list.Count] hello; // 必须在对象初始化器外赋值 // 或者使用集合初始化器 var dict new Dictionarystring, 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 Liststring { [^1] hello }; // 与属性初始化结合 var grid new Grid { [0, 0] A1, [0, 1] A2, [1, 0] B1 };使用场景// 集合初始化 var stack new Stackint { [^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 CacheT { private readonly Lock _lock new(); private readonly Dictionarystring, T _cache new(); public T GetOrAdd(string key, FuncT factory) { lock (_lock) { if (!_cache.TryGetValue(key, out var value)) { value factory(); _cache[key] value; } return value; } } }ref struct 接口适合的场景// 高性能解析器 ref struct JsonParser : IDisposable { private ReadOnlySpanchar _json; public JsonParser(ReadOnlySpanchar json) { _json json; } public void Dispose() { // 清理资源 } } // 可以与泛型方法配合使用 void ProcessT(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 RingBufferint(100); ringBuffer[^1] 42; // 直接设置最后一个位置迁移建议自动迁移C# 13 特性大部分向后兼容PropertyGroup LangVersion13/LangVersion /PropertyGroup需要注意的 breaking changesLock 类型如果代码检查lock对象的类型可能会受影响method group类型推断可能推断出不同的类型overload 优先级可能改变现有代码的重载选择隐式索引器访问如果代码中已有类似语法可能会产生歧义一句话总结C# 13 是泛型系统的突破ref struct 实现接口和 allows ref struct 让 C# 的类型系统更加强大。官方文档Whats new in C# 13params collectionsNew lock typeref struct interfaces示例代码.NET 新特性巡礼全系列配套示例代码含 dotnet 8/9/10GitHubGitHub - LadyKiller1025/dotnet-feature-tour-demos: .NET Feature Tour - Code Demos (.NET 8/9/10) · GitHubGiteehttps://gitee.com/qakjhzx/dotnet-feature-tour-demos 欢迎点赞、收藏、转发你的支持是我持续创作的动力