以下是按C#版本从低到高整理的.NET相关版本特性,补充了发布年份及对应的.NET Core/.NET版本信息,包含特性概念、作用、优势及示例:
C# 6.0
- 对应版本:.NET Framework 4.6(2015年)、.NET Core 1.0(2016年)
- 核心特性:
-
自动属性初始化器
- 概念:属性声明时直接赋值默认值,无需在构造函数中初始化。
- 作用:减少构造函数中的重复代码,默认值更直观。
- 优势:代码简洁,初始化逻辑集中在属性定义处。
- 示例:
public class User {public string Username { get; set; } = "guest"; // 直接初始化public int LoginCount { get; set; } = 0; }
-
字符串插值($)
- 概念:用
$
标记字符串,通过{变量/表达式}
直接嵌入值,替代String.Format
。 - 作用:简化字符串拼接,避免占位符顺序错误。
- 优势:可读性提升,编写效率更高。
- 示例:
int id = 100; string msg = $"User ID: {id}, Status: {id > 0 ? "Valid" : "Invalid"}";
- 概念:用
-
空传播运算符(?.)
- 概念:访问成员前自动检查对象是否为
null
,避免NullReferenceException
。 - 作用:替代多层
if (obj != null)
判断。 - 优势:代码紧凑,减少空值判断冗余。
- 示例:
int? length = user?.Address?.City?.Length; // 任意环节为null则返回null
- 概念:访问成员前自动检查对象是否为
C# 7.0/7.1
- 对应版本:.NET Framework 4.7(2017年)、.NET Core 2.0(2017年)
- 核心特性:
-
元组(Tuples)
- 概念:轻量级数据结构,可直接存储多个不同类型的值,无需定义类。
- 作用:方便方法返回多值,替代
out
参数或自定义实体类。 - 优势:语法简洁,支持解构赋值。
- 示例:
(string Name, int Age) GetUser() => ("Tom", 28); // 元组返回值 var (name, age) = GetUser(); // 解构
-
模式匹配(is表达式)
- 概念:结合类型判断与变量赋值,简化类型转换逻辑。
- 作用:替代
as
转换+null
检查的繁琐写法。 - 优势:逻辑清晰,减少类型转换错误。
- 示例:
if (input is int num) { // 若input是int,直接赋值给numConsole.WriteLine(num * 2); }
-
本地函数
- 概念:在方法内部定义的函数,仅在当前方法内可见。
- 作用:封装仅当前方法使用的逻辑,避免命名空间污染。
- 优势:提高代码内聚性,减少类级冗余方法。
- 示例:
int Calculate(int x, int y) {int Multiply(int a, int b) => a * b; // 本地函数return Multiply(x, y) + 10; }
C# 8.0
- 对应版本:.NET Core 3.0(2019年)、.NET Standard 2.1(2019年)
- 核心特性:
-
可空引用类型
- 概念:通过
?
标记引用类型可能为null
,编译器主动检查空值风险。 - 作用:提前暴露潜在的
NullReferenceException
,降低运行时错误。 - 优势:代码更健壮,空值逻辑显性化。
- 示例:
#nullable enable string? nullableStr = null; // 允许为null string nonNullableStr = null; // 编译警告(禁止为null)
- 概念:通过
-
默认接口方法
- 概念:接口中可定义带实现的方法,无需所有实现类强制重写。
- 作用:安全扩展现有接口,兼容旧版本实现类。
- 优势:接口演进更灵活,避免“修改接口导致所有实现崩溃”。
- 示例:
public interface IDataStore {void Save(string data); // 抽象方法void LogError(string error) => Console.WriteLine($"Error: {error}"); // 默认实现 }
-
异步流(IAsyncEnumerable
) - 概念:结合异步与迭代器,支持逐个返回异步结果(非一次性加载)。
- 作用:适用于大数据流或网络请求,减少内存占用。
- 优势:降低内存压力,支持异步迭代。
- 示例:
async IAsyncEnumerable<int> FetchDataAsync() {for (int i = 0; i < 3; i++) {await Task.Delay(100); // 模拟异步操作yield return i;} } // 消费:await foreach await foreach (var item in FetchDataAsync()) { ... }
C# 9.0
- 对应版本:.NET 5.0(2020年11月,首次统一.NET平台,替代.NET Core)
- 核心特性:
-
记录类型(Record)
- 概念:不可变引用类型,自动实现值相等性(而非引用相等性)。
- 作用:简化“仅存储数据”的类,自动生成
Equals
、ToString
等方法。 - 优势:不可变性确保线程安全,减少相等性检查代码。
- 示例:
public record Product(string Name, decimal Price); var p1 = new Product("Laptop", 5000); var p2 = new Product("Laptop", 5000); Console.WriteLine(p1 == p2); // True(值相等)
-
顶级语句
- 概念:无需显式定义
Program
类和Main
方法,直接编写代码作为程序入口。 - 作用:简化小程序或脚本的编写,减少样板代码。
- 优势:降低入门门槛,代码更简洁。
- 示例:
// 完整程序,无需class和Main Console.WriteLine("Hello .NET 5!");
- 概念:无需显式定义
-
模式匹配增强(范围模式)
- 概念:支持
>
,<
,>=
,<=
等比较运算符在模式匹配中使用。 - 作用:简化范围判断逻辑,替代多层
if-else
。 - 优势:逻辑直观,代码紧凑。
- 示例:
string GetGrade(int score) => score switch {>= 90 => "A",>= 60 and < 90 => "B",_ => "C" };
- 概念:支持
C# 10.0
- 对应版本:.NET 6.0(2021年11月)
- 核心特性:
-
文件范围的命名空间
- 概念:用
namespace 命名空间;
声明,整个文件的类型自动属于该命名空间(无需大括号)。 - 作用:减少代码缩进,简化命名空间声明。
- 优势:避免多层嵌套,提高可读性。
- 示例:
namespace MyApp; // 文件范围命名空间 class Order { ... } // 自动属于MyApp
- 概念:用
-
全局using指令
- 概念:在文件中用
global using 命名空间;
声明,整个项目自动引入该命名空间。 - 作用:减少每个文件中的重复
using
语句。 - 优势:统一命名空间管理,简化代码。
- 示例:
// GlobalUsings.cs global using System; global using System.Linq; // 其他文件直接使用,无需重复using var list = new List<int>();
- 概念:在文件中用
-
密封记录(Sealed Record)
- 概念:
sealed record
禁止被继承,确保记录类型的行为稳定性。 - 作用:限制继承层次,避免意外修改记录逻辑。
- 优势:提高代码可维护性,防止继承滥用。
- 示例:
public sealed record Point(int X, int Y); // public record ExtendedPoint : Point { } // 编译错误:无法继承密封记录
- 概念:
C# 11.0
- 对应版本:.NET 7.0(2022年11月)
- 核心特性:
-
原始字符串字面量(Triple Quotes)
- 概念:用
"""
包裹字符串,支持多行文本和特殊字符(无需转义)。 - 作用:简化JSON、SQL、HTML等复杂格式字符串的编写。
- 优势:减少转义符(
\
),提高可读性。 - 示例:
string sql = """SELECT * FROM UsersWHERE Name = "John" AND Age > 30 """; // 无需转义双引号和换行
- 概念:用
-
required成员
- 概念:用
required
标记属性,强制实例化时必须显式初始化。 - 作用:确保对象关键属性不被遗漏,替代构造函数参数检查。
- 优势:支持对象初始化器,同时保证必填项。
- 示例:
public class Book {public required string Title { get; set; } // 必须初始化 } var book = new Book { Title = "C# 11 Guide" }; // 正确 // var book = new Book(); // 编译错误:缺少required成员
- 概念:用
-
泛型属性
- 概念:属性类可定义为泛型(
class MyAttr<T> : Attribute
),使用时直接指定类型。 - 作用:简化需要类型信息的属性场景(如验证、序列化)。
- 优势:避免字符串传递类型名,提高类型安全性。
- 示例:
public class TypeValidatorAttribute<T> : Attribute { } [TypeValidator<string>] // 直接指定泛型参数 public class DataProcessor { }
- 概念:属性类可定义为泛型(
C# 12.0
- 对应版本:.NET 8.0(2023年11月)
- 核心特性:
-
集合表达式
- 概念:用统一的
[]
语法初始化数组、List
、HashSet
等集合,支持展开(..
)。 - 作用:替代不同集合的初始化器语法,统一风格。
- 优势:代码简洁,支持集合合并。
- 示例:
int[] arr = [1, 2, 3]; List<int> list = [4, 5, .. arr]; // 展开arr,结果:[4,5,1,2,3]
- 概念:用统一的
-
类/结构体的主构造函数
- 概念:在类声明时直接定义构造函数参数,参数可在类内直接使用。
- 作用:简化字段与构造函数的绑定代码。
- 优势:减少“定义字段→构造函数赋值”的重复步骤。
- 示例:
public class Car(string model, int year) {public string Model => model;public int Year => year; } var car = new Car("Tesla", 2023);
-
扩展方法的泛型约束增强
- 概念:扩展方法的
this
参数可添加更灵活的泛型约束(如where T : struct
)。 - 作用:精确限制扩展方法的适用类型,提高安全性。
- 优势:避免扩展方法被误用在不兼容类型上。
- 示例:
public static T Square<T>(this T value) where T : struct {return value * value; // 仅适用于值类型(如int, double) }
- 概念:扩展方法的
总结
从2015年的C# 6.0到2023年的C# 12.0,.NET(含.NET Core)的发展趋势是:
- 简化样板代码(如顶级语句、集合表达式);
- 增强类型安全(如可空引用类型、泛型属性);
- 提升开发效率(如字符串插值、模式匹配);
- 优化兼容性(如默认接口方法)。
每个版本的特性均围绕“减少冗余、提高健壮性、降低复杂度”展开,逐步提升C#的开发体验。