前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >C#高性能开发之类型系统:从C# 7.0 到C# 14的类型系统演进全景

C#高性能开发之类型系统:从C# 7.0 到C# 14的类型系统演进全景

作者头像
AI.NET 极客圈
发布于 2025-04-24 06:52:24
发布于 2025-04-24 06:52:24
3400
代码可运行
举报
文章被收录于专栏:AI.NET极客圈AI.NET极客圈
运行总次数:0
代码可运行

自C# 7.0以来,C#语言在类型系统方面引入了众多新数据类型、类型构造和语言特性,以提升性能、类型安全性和开发效率。本文全面整理了从C# 7.0到C# 14.0(截至2025年4月,C# 14.0为预览版)类型系统的新增内容,包括值元组、Span<T>ReadOnlySpan<T>Memory<T>ReadOnlyMemory<T>、可空引用类型、记录、本机大小整数、记录结构、内联数组,以及其他增强(如只读结构、泛型数学支持)。

版本概览

以下是C# 7.0至C# 14.0中类型系统新增或增强的主要内容:

C# 版本

新增/增强内容

发布年份

描述

7.0

值元组(Value Tuples)

2017

轻量级数据结构,支持多值返回和解构

7.2

Span, ReadOnlySpan, 只读结构, 引用结构

2017

高性能内存操作和不可变/栈分配结构体

8.0

可空引用类型, Memory, ReadOnlyMemory

2019

空值安全性和托管内存块

9.0

记录, 本机大小整数, 初始化器专用类型

2020

值语义引用类型、本机整数和不可变属性

10.0

记录结构, 全局 using 指令

2021

值类型记录和简化类型引用

11.0

必需成员, 泛型数学支持, 文件局部类型

2022

强制初始化、泛型运算和类型作用域限制

12.0

内联数组

2023

固定大小数组结构,优化性能

13.0

参数集合扩展, 引用结构接口支持, 部分属性

2024

扩展params、ref struct接口和部分属性定义

14.0

field 关键字, 隐式 span 转换, nameof 增强, lambda 参数修饰符, partial 成员扩展, 空条件赋值

2025(待定)

增强属性访问、span 使用、泛型处理、lambda 表达、partial 类型和空值处理

以下按版本逐一详述,每节包含特性表格、代码示例和分析。

C# 7.0:值元组

特性表格

类型/构造

描述

主要用途

注意事项

值元组 (Value Tuples)

轻量级值类型,支持多值返回、命名元素和解构

方法返回多个值、临时数据分组

值类型,栈分配;.NET Framework需引用System.ValueTuple包

概述

值元组基于System.ValueTuple,允许方法返回多个值,支持命名元素和解构,简化数据传递。

语法

  • 声明:(type1, type2, ...) tupleName = (value1, value2, ...);
  • 命名元素:(type1 name1, type2 name2, ...) tupleName = (value1, value2, ...);
  • 解构:var (var1, var2, ...) = tupleName;

示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public (int id, string name) GetPerson()
{
    return (1, "Alice");
}

var person = GetPerson();
Console.WriteLine($"ID: {person.id}, Name: {person.name}");

// 解构
var (id, name) = GetPerson();
Console.WriteLine($"ID: {id}, Name: {name}");

适用场景

  • 方法返回多个相关值。
  • 临时数据分组,无需定义类或结构。
  • 解构赋值,简化代码。

注意事项

  • 值类型,适合轻量数据。
  • .NET Framework项目需引用System.ValueTuple NuGet包。

C# 7.2:Span, ReadOnlySpan, 只读结构, 引用结构

特性表格

类型/构造

描述

主要用途

注意事项

Span

表示连续内存块的引用,支持读写

高性能数组/内存操作

ref struct,栈分配,生命周期限制

ReadOnlySpan

只读连续内存块引用

高性能只读操作

同上,需确保内存边界安全

只读结构 (readonly struct)

不可变结构体,优化性能

不可变数据结构

所有实例字段必须只读

引用结构 (ref struct)

栈分配结构体

高性能内存管理

不可boxing或作为接口实现

概述

Span<T>ReadOnlySpan<T>是高性能值类型,表示连续内存块引用,适合数组和本机内存操作。readonly struct确保结构体不可变,ref struct限制为栈分配,支持Span<T>等类型。

语法

  • Span: Span<T> span = collection.AsSpan();
  • ReadOnlySpan: ReadOnlySpan<T> readOnlySpan = collection.AsSpan();
  • 只读结构: readonly struct StructName { ... }
  • 引用结构: ref struct StructName { ... }

示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Span<T> 和 ReadOnlySpan<T>
int[] numbers = [1, 2, 3, 4, 5];
Span<int> span = numbers.AsSpan(1, 3);
span[0] = 10;
Console.WriteLine(string.Join(", ", span.ToArray())); // 10, 3, 4

ReadOnlySpan<char> text = "Hello".AsSpan();
Console.WriteLine(text.Slice(0, 2).ToString()); // He

// 只读结构
readonlystruct Point
{
    publicint X { get; init; }
    publicint Y { get; init; }
}
Point point = new() { X = 1, Y = 2 };
Console.WriteLine($"({point.X}, {point.Y})"); // (1, 2)

// 引用结构
refstruct Buffer
{
    public Span<int> Data;
    public Buffer(Span<int> data) => Data = data;
}
Buffer buffer = new(numbers.AsSpan());
buffer.Data[0] = 10;
Console.WriteLine(numbers[0]); // 10

适用场景

  • 高性能字符串解析、缓冲区处理。
  • 不可变数据结构(只读结构)。
  • 避免堆分配(引用结构)。

注意事项

  • Span<T>ReadOnlySpan<T>不可用于异步方法。
  • ref struct限制严格,需管理生命周期。

C# 8.0:可空引用类型, Memory, ReadOnlyMemory

特性表格

类型/构造

描述

主要用途

注意事项

可空引用类型

引用类型可标记为可空,默认非null

增强空值安全性

需启用可空上下文,处理编译器警告

Memory

托管内存块,支持读写

异步和高性能内存操作

适合异步场景,需管理生命周期

ReadOnlyMemory

只读托管内存块

只读异步内存操作

同上

概述

可空引用类型通过?后缀指定引用类型是否可为null,减少空引用异常。Memory<T>ReadOnlyMemory<T>表示托管内存块,支持异步场景。

语法

  • 可空引用类型: string? nullable; string nonNullable;
  • Memory: Memory<T> memory = collection.AsMemory();
  • ReadOnlyMemory: ReadOnlyMemory<T> readOnlyMemory = collection.AsMemory();

示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 可空引用类型
#nullable enable
string nonNullable = "Hello";
string? nullable = null;
if (nullable != null)
{
    Console.WriteLine(nullable.Length);
}

// Memory<T> 和 ReadOnlyMemory<T>
int[] numbers = [1, 2, 3, 4, 5];
Memory<int> memory = numbers.AsMemory(1, 3);
Span<int> span = memory.Span;
span[0] = 10;
Console.WriteLine(string.Join(", ", memory.ToArray())); // 10, 3, 4

ReadOnlyMemory<char> text = "Hello".AsMemory();
Console.WriteLine(text.Slice(0, 2).Span.ToString()); // He

适用场景

  • 增强空值安全性(可空引用类型)。
  • 异步内存操作(Memory)。
  • 只读数据传递(ReadOnlyMemory)。

注意事项

  • 可空引用类型需显式启用。
  • Memory生命周期需管理。

C# 9.0:记录, 本机大小整数, 初始化器专用类型

特性表格

类型/构造

描述

主要用途

注意事项

记录 (Records)

具有值语义的引用类型,默认不可变

数据建模,值相等性

默认不可变,可添加可变行为

本机大小整数 (nint, nuint)

本机大小整数,映射IntPtr/UIntPtr

本机代码互操作

平台依赖,需考虑兼容性

初始化器专用类型 (init-only setters)

初始化后不可变属性

不可变数据模型

仅初始化时可赋值

概述

记录是具有值语义的引用类型,自动实现相等性。nintnuint支持本机大小整数。init修饰符增强属性不可变性。

语法

  • 记录: public record ClassName(type1 Property1, ...);
  • 本机大小整数: nint nativeInt; nuint nativeUInt;
  • init-only: public type Property { get; init; }

示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 记录
public record Person(string FirstName, string LastName);
var person1 = new Person("Alice", "Smith");
var person2 = new Person("Alice", "Smith");
Console.WriteLine(person1 == person2); // True
var person3 = person1 with { LastName = "Johnson" };
Console.WriteLine(person3); // Person { FirstName = Alice, LastName = Johnson }

// 本机大小整数
nint nativeInt = 42;
nuint nativeUInt = 42u;
Console.WriteLine($"Native int: {nativeInt}, Native uint: {nativeUInt}");

// 初始化器专用类型
publicclassStudent
{
    publicstring Name { get; init; }
}
var student = new Student { Name = "Alice" };
Console.WriteLine(student.Name); // Alice

适用场景

  • 数据传输对象(记录)。
  • 本机代码互操作(nint, nuint)。
  • 不可变数据模型(init-only)。

注意事项

  • 记录支持继承,需保持值语义。
  • 本机大小整数平台依赖。

C# 10.0:记录结构, 全局 using 指令

特性表格

类型/构造

描述

主要用途

注意事项

记录结构 (Record Structs)

值类型的记录,结合值语义和性能

小型数据结构

值类型,复制成本需考虑

全局 using 指令

全局导入命名空间

简化类型引用

需平衡代码可读性

概述

记录结构将记录特性扩展到值类型,结合值语义和性能。全局using简化类型引用。

语法

  • 记录结构: public record struct StructName(type1 Property1, ...);
  • 全局 using: global using System;

示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 记录结构
public record struct Point(int X, int Y);
var point1 = new Point(1, 2);
var point2 = new Point(1, 2);
Console.WriteLine(point1 == point2); // True
var point3 = point1 with { X = 3 };
Console.WriteLine(point3); // Point { X = 3, Y = 2 }

// 全局 using(假设已在文件顶部)
Console.WriteLine("Hello, World!"); // 无需显式 using System

适用场景

  • 值类型数据建模(记录结构)。
  • 大型项目命名空间管理(全局 using)。

注意事项

  • 记录结构复制成本需关注。
  • 全局 using 需谨慎使用。

C# 11.0:必需成员, 泛型数学支持, 文件局部类型

特性表格

类型/构造

描述

主要用途

注意事项

必需成员 (required members)

强制成员初始化

确保关键字段初始化

需配合初始化器或构造函数

泛型数学支持

静态抽象接口成员支持泛型运算

泛型算法库

需运行时支持(.NET 7+)

文件局部类型 (file modifier)

限制类型作用域至文件

隔离辅助类型

仅限文件作用域

概述

required修饰符强制成员初始化。泛型数学支持通过接口实现数值运算。file修饰符限制类型作用域。

语法

  • 必需成员: public required type Property { get; set; }
  • 泛型数学: interface INumber<T> { static abstract T operator +(T, T); }
  • 文件局部类型: file class ClassName { ... }

示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 必需成员
publicclassPerson
{
    public required string Name { get; set; }
}
var person = new Person { Name = "Alice" };
Console.WriteLine(person.Name); // Alice

// 泛型数学支持
publicinterfaceINumber<T> whereT : INumber<T>
{
    static abstract T Add(T left, T right);
}
publicreadonlystruct MyNumber : INumber<MyNumber>
{
    publicint Value { get; init; }
    public MyNumber(int value) => Value = value;
    public static MyNumber Add(MyNumber left, MyNumber right) => new(left.Value + right.Value);
}
MyNumber a = new(1);
MyNumber b = new(2);
var result = MyNumber.Add(a, b);
Console.WriteLine(result.Value); // 3

// 文件局部类型
file classHelper
{
    public static void Log(string message) => Console.WriteLine(message);
}
Helper.Log("Test");

适用场景

  • API 设计(必需成员)。
  • 泛型数值计算(泛型数学)。
  • 代码生成(文件局部类型)。

注意事项

  • 必需成员需明确初始化。
  • 泛型数学需运行时支持。

C# 12.0:内联数组

特性表格

类型/构造

描述

主要用途

注意事项

内联数组 (Inline Arrays)

固定大小数组结构,栈分配

高性能固定大小数组

固定大小,仅限结构体内

概述

内联数组通过[InlineArray]特性定义固定大小数组结构,优化性能。

语法

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[InlineArray(length)]
public struct StructName
{
    private elementType _element0;
}

示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[InlineArray(10)]
public struct Buffer
{
    private int _element0;
}
Buffer buffer = new();
buffer[0] = 1;
buffer[9] = 10;
Console.WriteLine(buffer[0]); // 1

适用场景

注意事项

  • 固定大小,运行时不可调整。

C# 13.0:参数集合扩展, 引用结构接口支持, 部分属性

特性表格

类型/构造

描述

主要用途

注意事项

参数集合扩展 (params Span等)

扩展params支持Span等

高性能参数传递

需确保Span生命周期

引用结构接口支持

允许ref struct实现接口

扩展ref struct能力

仍受ref struct限制

部分属性 (partial properties)

支持partial类型部分属性

代码生成

需确保定义一致

概述

参数集合扩展支持Span<T>等类型。ref struct可实现接口。部分属性支持分文件定义。

语法

  • 参数集合: void Method(params Span<T> spans);
  • 引用结构接口: ref struct StructName : IInterface { ... }
  • 部分属性: public partial type Property { get; set; }

示例代码

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 参数集合扩展
public void Process(params Span<int> spans)
{
    foreach (var span in spans)
        Console.WriteLine(string.Join(", ", span.ToArray()));
}
int[] numbers = [1, 2, 3];
Process(numbers.AsSpan(0, 2), numbers.AsSpan(2, 1)); // 1, 2 和 3

// 引用结构接口支持
publicinterfaceIBuffer
{
    void Process();
}
refstruct Buffer : IBuffer
{
    public Span<int> Data;
    public Buffer(Span<int> data) => Data = data;
    public void Process() => Data[0] = 10;
}
Buffer buffer = new(numbers.AsSpan());
buffer.Process();
Console.WriteLine(numbers[0]); // 10

// 部分属性
publicpartialclassPerson
{
    publicpartialstring Name { get; set; }
}
publicpartialclassPerson
{
    publicpartialstring Name { get => _name; set => _name = value; }
    privatestring _name;
}
var person = new Person { Name = "Alice" };
Console.WriteLine(person.Name); // Alice

适用场景

  • 高性能参数传递(参数集合)。
  • 扩展ref struct(接口支持)。
  • 代码生成(部分属性)。

注意事项

  • 参数集合需管理Span生命周期。
  • 部分属性需确保一致性。

C# 14.0:field 关键字, 隐式 span 转换, nameof 增强, lambda 参数修饰符, partial 成员扩展, 空条件赋值

特性表格

类型/构造

描述

主要用途

注意事项

field 关键字

允许在属性访问器中直接访问 backing field

简化属性实现

可能与现有字段名冲突,需使用 @field 或 this.field 区分

隐式 span 转换

支持 Span<T>、ReadOnlySpan<T> 与数组间的隐式转换

更自然地使用 span 类型

需注意 span 的生命周期

nameof 支持未绑定泛型

允许 nameof 使用未绑定泛型类型,如 nameof(List<>)

泛型编程中的类型名称获取

-

lambda 参数修饰符

允许 lambda 参数使用 ref、out 等修饰符,无需指定类型

增强 lambda 表达式的灵活性

params 仍需指定类型

partial 构造函数和事件

扩展 partial 成员到实例构造函数和事件

分离定义和实现,适合代码生成

需确保 defining 和 implementing 声明一致

空条件赋值

允许在赋值左侧使用 ?. 和 ?[],仅在左侧非 null 时赋值

简化 null 检查

不支持 ++ 和 --

概述

C# 14.0(预计2025年随.NET 10发布,截至2025年4月为预览版)引入了一系列语言特性,旨在提高开发效率和代码可读性,包括 field 关键字、隐式 span 转换、nameof 增强、lambda 参数修饰符、partial 成员扩展和空条件赋值。虽然未引入全新数据类型,但这些特性显著增强了现有类型的用法。

field 关键字

概述

field 关键字允许在属性访问器中直接访问编译器生成的 backing field,无需显式声明。

示例代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Person
{
    public string Name
    {
        get => field;
        set => field = value?.Trim();
    }
}
var person = new Person { Name = " Alice " };
Console.WriteLine(person.Name); // Alice
适用场景
  • 简化属性实现,特别是需要对 setter 进行处理时。
注意事项
  • 如果类中已有名为 field 的字段,需使用 @fieldthis.field 区分。
  • 作为C# 13.0的预览特性,C# 14.0正式支持,详见field 关键字。

隐式 span 转换

概述

C# 14.0 为 Span<T>ReadOnlySpan<T> 提供了与数组的隐式转换,使其使用更加自然。

示例代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Span<int> span = new int[] {1, 2, 3};
int[] array = span.ToArray();
Console.WriteLine(string.Join(", ", array)); // 1, 2, 3
适用场景
  • 高性能场景中,减少显式转换。
  • 与数组和 span 类型交互。
注意事项
  • 需确保 span 的生命周期管理,详见Span 转换。

nameof 支持未绑定泛型

概述

允许 nameof 操作符使用未绑定泛型类型。

示例代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
string listName = nameof(List<>);
Console.WriteLine(listName); // List
适用场景
  • 泛型编程中,获取类型名称。
注意事项
  • 简单但强大的增强,适合反射场景。

lambda 参数修饰符

概述

允许在 lambda 表达式中为参数添加修饰符,如 refout 等,无需指定类型。

示例代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
var increment = (ref int x) => x++;
int num = 5;
increment(ref num);
Console.WriteLine(num); // 6
适用场景
  • 需要在 lambda 中修改外部变量。
注意事项
  • params 仍需指定类型,详见lambda 表达式。

partial 构造函数和事件

概述

扩展 partial 成员到实例构造函数和事件,允许在 partial 类型中分离定义和实现。

示例代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// File1.cs
publicpartialclassMyClass
{
    public partial MyClass(int x);
    publicpartialevent EventHandler MyEvent;
}

// File2.cs
publicpartialclassMyClass
{
    public partial MyClass(int x) { }
    publicpartialevent EventHandler MyEvent;
}
适用场景
  • 代码生成场景,如 UI 设计器。
注意事项
  • 需确保 defining 和 implementing 声明一致,详见partial 成员。

空条件赋值

概述

允许在赋值语句的左侧使用 ?.?[],仅当左侧非 null 时执行赋值。

示例代码
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
string? text = null;
text?.Length = 5; // 不执行赋值

List<int>? list = null;
list?[0] = 10; // 不执行赋值

list = new List<int> { 0 };
list?[0] = 10; // 执行赋值,list[0] = 10
Console.WriteLine(list[0]); // 10
适用场景
  • 简化 null 检查,避免 NullReferenceException。
注意事项
  • 不支持 ++-- 操作,详见空条件赋值。

结语

C# 7.0至C# 14.0的类型系统新增内容涵盖了值元组、Span、ReadOnlySpan、Memory、ReadOnlyMemory、可空引用类型、记录、本机大小整数、记录结构、内联数组等数据类型,以及只读结构、引用结构、必需成员、泛型数学支持等增强。C# 14.0通过field关键字、隐式 span 转换等特性进一步优化了现有类型的用法。这些特性满足了从高性能内存管理到类型安全建模的多种需求。资深C#工程师可根据场景选择类型,如使用Span优化性能,记录建模数据。由于C# 14.0尚在预览阶段,建议关注dotnet/roslyn以获取最新更新。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-04-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 AI.NET极客圈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 版本概览
  • C# 7.0:值元组
    • 特性表格
    • 概述
    • 语法
    • 示例代码
    • 适用场景
    • 注意事项
  • C# 7.2:Span, ReadOnlySpan, 只读结构, 引用结构
    • 特性表格
    • 概述
    • 语法
    • 示例代码
    • 适用场景
    • 注意事项
  • C# 8.0:可空引用类型, Memory, ReadOnlyMemory
    • 特性表格
    • 概述
    • 语法
    • 示例代码
    • 适用场景
    • 注意事项
  • C# 9.0:记录, 本机大小整数, 初始化器专用类型
    • 特性表格
    • 概述
    • 语法
    • 示例代码
    • 适用场景
    • 注意事项
  • C# 10.0:记录结构, 全局 using 指令
    • 特性表格
    • 概述
    • 语法
    • 示例代码
    • 适用场景
    • 注意事项
  • C# 11.0:必需成员, 泛型数学支持, 文件局部类型
    • 特性表格
    • 概述
    • 语法
    • 示例代码
    • 适用场景
    • 注意事项
  • C# 12.0:内联数组
    • 特性表格
    • 概述
    • 语法
    • 示例代码
    • 适用场景
    • 注意事项
  • C# 13.0:参数集合扩展, 引用结构接口支持, 部分属性
    • 特性表格
    • 概述
    • 语法
    • 示例代码
    • 适用场景
    • 注意事项
  • C# 14.0:field 关键字, 隐式 span 转换, nameof 增强, lambda 参数修饰符, partial 成员扩展, 空条件赋值
    • 特性表格
    • 概述
    • field 关键字
      • 概述
      • 示例代码
      • 适用场景
      • 注意事项
    • 隐式 span 转换
      • 概述
      • 示例代码
      • 适用场景
      • 注意事项
    • nameof 支持未绑定泛型
      • 概述
      • 示例代码
      • 适用场景
      • 注意事项
    • lambda 参数修饰符
      • 概述
      • 示例代码
      • 适用场景
      • 注意事项
    • partial 构造函数和事件
      • 概述
      • 示例代码
      • 适用场景
      • 注意事项
    • 空条件赋值
      • 概述
      • 示例代码
      • 适用场景
      • 注意事项
  • 结语
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档