ASP.NET MVC .浅析

灾徒究热类型/构造 描述 主要用途 注意事项

值元组 (Value Tuples) 轻量级值类型,支持多值返回、命名元素和解构 方法返回多个值、临时数据分组 值类型,栈分配;.NET Framework需引用System.ValueTuple包

概述

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

语法

声明:(type1, type2, ...) tupleName = (value1, value2, ...);

命名元素:(type1 name1, type2 name2, ...) tupleName = (value1, value2, ...);

解构:var (var1, var2, ...) = tupleName;

示例代码

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

语法

Span: Span span = collection.AsSpan();

ReadOnlySpan: ReadOnlySpan

只读结构: readonly struct StructName { ... }

引用结构: ref struct StructName { ... }

示例代码

// Span 和 ReadOnlySpan

int[] numbers = [1, 2, 3, 4, 5];

Span span = numbers.AsSpan(1, 3);

span[0] = 10;

Console.WriteLine(string.Join(", ", span.ToArray())); // 10, 3, 4

ReadOnlySpan text = "Hello".AsSpan();

Console.WriteLine(text.Slice(0, 2).ToString()); // He

// 只读结构

readonly struct Point

{

public int X { get; init; }

public int Y { get; init; }

}

Point point = new() { X = 1, Y = 2 };

Console.WriteLine($"({point.X}, {point.Y})"); // (1, 2)

// 引用结构

ref struct Buffer

{

public Span Data;

public Buffer(Span data) => Data = data;

}

Buffer buffer = new(numbers.AsSpan());

buffer.Data[0] = 10;

Console.WriteLine(numbers[0]); // 10

适用场景

高性能字符串解析、缓冲区处理。

不可变数据结构(只读结构)。

避免堆分配(引用结构)。

注意事项

Span和ReadOnlySpan不可用于异步方法。

ref struct限制严格,需管理生命周期。

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

特性表格

类型/构造 描述 主要用途 注意事项

可空引用类型 引用类型可标记为可空,默认非null 增强空值安全性 需启用可空上下文,处理编译器警告

Memory 托管内存块,支持读写 异步和高性能内存操作 适合异步场景,需管理生命周期

ReadOnlyMemory 只读托管内存块 只读异步内存操作 同上

概述

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

语法

可空引用类型: string? nullable; string nonNullable;

Memory: Memory memory = collection.AsMemory();

ReadOnlyMemory: ReadOnlyMemory readOnlyMemory = collection.AsMemory();

示例代码

// 可空引用类型

#nullable enable

string nonNullable = "Hello";

string? nullable = null;

if (nullable != null)

{

Console.WriteLine(nullable.Length);

}

// Memory 和 ReadOnlyMemory

int[] numbers = [1, 2, 3, 4, 5];

Memory memory = numbers.AsMemory(1, 3);

Span span = memory.Span;

span[0] = 10;

Console.WriteLine(string.Join(", ", memory.ToArray())); // 10, 3, 4

ReadOnlyMemory 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) 初始化后不可变属性 不可变数据模型 仅初始化时可赋值

概述

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

语法

记录: public record ClassName(type1 Property1, ...);

本机大小整数: nint nativeInt; nuint nativeUInt;

init-only: public type Property { get; init; }

示例代码

// 记录

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}");

// 初始化器专用类型

public class Student

{

public string 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;

示例代码

// 记录结构

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 { static abstract T operator +(T, T); }

文件局部类型: file class ClassName { ... }

示例代码

// 必需成员

public class Person

{

public required string Name { get; set; }

}

var person = new Person { Name = "Alice" };

Console.WriteLine(person.Name); // Alice

// 泛型数学支持

public interface INumber where T : INumber

{

static abstract T Add(T left, T right);

}

public readonly struct MyNumber : INumber

{

public int 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 class Helper

{

public static void Log(string message) => Console.WriteLine(message);

}

Helper.Log("Test");

适用场景

API 设计(必需成员)。

泛型数值计算(泛型数学)。

代码生成(文件局部类型)。

注意事项

必需成员需明确初始化。

泛型数学需运行时支持。

C# 12.0:内联数组

特性表格

类型/构造 描述 主要用途 注意事项

内联数组 (Inline Arrays) 固定大小数组结构,栈分配 高性能固定大小数组 固定大小,仅限结构体内

概述

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

语法

InlineArray(length)

public struct StructName

{

private elementType _element0;

}

示例代码

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等类型。ref struct可实现接口。部分属性支持分文件定义。

语法

参数集合: void Method(params Span spans);

引用结构接口: ref struct StructName : IInterface { ... }

部分属性: public partial type Property { get; set; }

示例代码

// 参数集合扩展

public void Process(params Span 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

// 引用结构接口支持

public interface IBuffer

{

void Process();

}

ref struct Buffer : IBuffer

{

public Span Data;

public Buffer(Span data) => Data = data;

public void Process() => Data[0] = 10;

}

Buffer buffer = new(numbers.AsSpan());

buffer.Process();

Console.WriteLine(numbers[0]); // 10

// 部分属性

public partial class Person

{

public partial string Name { get; set; }

}

public partial class Person

{

public partial string Name { get => _name; set => _name = value; }

private string _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、ReadOnlySpan 与数组间的隐式转换 更自然地使用 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,无需显式声明。

示例代码

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 的字段,需使用 @field 或 this.field 区分。

作为C# 13.0的预览特性,C# 14.0正式支持,详见field 关键字。

隐式 span 转换

概述

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

示例代码

Span span = new int[] {1, 2, 3};

int[] array = span.ToArray();

Console.WriteLine(string.Join(", ", array)); // 1, 2, 3

适用场景

高性能场景中,减少显式转换。

与数组和 span 类型交互。

注意事项

需确保 span 的生命周期管理,详见Span 转换。

nameof 支持未绑定泛型

概述

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

示例代码

string listName = nameof(List<>);

Console.WriteLine(listName); // List

适用场景

泛型编程中,获取类型名称。

注意事项

简单但强大的增强,适合反射场景。

lambda 参数修饰符

概述

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

示例代码

var increment = (ref int x) => x++;

int num = 5;

increment(ref num);

Console.WriteLine(num); // 6

适用场景

需要在 lambda 中修改外部变量。

注意事项

params 仍需指定类型,详见lambda 表达式。

partial 构造函数和事件

概述

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

示例代码

// File1.cs

public partial class MyClass

{

public partial MyClass(int x);

public partial event EventHandler MyEvent;

}

// File2.cs

public partial class MyClass

{

public partial MyClass(int x) { }

public partial event EventHandler MyEvent;

}

适用场景

代码生成场景,如 UI 设计器。

注意事项

需确保 defining 和 implementing 声明一致,详见partial 成员。

空条件赋值

概述

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

示例代码

string? text = null;

text?.Length = 5; // 不执行赋值

List? list = null;

list?[0] = 10; // 不执行赋值

list = new List { 0 };

list?[0] = 10; // 执行赋值,list[0] = 10

Console.WriteLine(list[0]); // 10

适用场景

简化 null 检查,避免 NullReferenceException。

注意事项

不支持 ++ 和 -- 操作,详见空条件赋值。