【.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 类型
之前的做法:使用 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 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
-
Lock 类型:如果代码检查
lock对象的类型,可能会受影响 -
method group:类型推断可能推断出不同的类型
-
overload 优先级:可能改变现有代码的重载选择
-
隐式索引器访问:如果代码中已有类似语法,可能会产生歧义
一句话总结
C# 13 是泛型系统的突破,ref struct 实现接口和 allows ref struct 让 C# 的类型系统更加强大。
官方文档
📦 示例代码:.NET 新特性巡礼全系列配套示例代码(含 dotnet 8/9/10)
💬 欢迎点赞、收藏、转发,你的支持是我持续创作的动力!
更多推荐

所有评论(0)