前言

今天大姚带领大家一起来看看 C# 13 中的新增几大功能,并了解其功能特性和实际应用场景。

前提准备

要体验 C# 13 新增的功能可以使用最新的 Visual Studio 2022 版本或 .NET 9 SDK 尝试这些功能。

Visual Studio 2022安装

.NET 9 SDK

params 集合

在 C# 13 中,params 的改进使其从可变数量的数组参数升级为可变数量的集合类型参数。这一改进通过支持高性能集合类型(如Span<T>、ReadOnlySpan<T>)和简化调用语法,显著提升了代码的灵活性和效率。

C# 13 中的 params 集合变得类型更灵活,满足更复杂的应用场景,并且性能得到了进一步的提升。

在 C# 13 之前:

params 仅支持一维数组(如params int[] listparams object[] list)。调用方法时需显式传递数组或数组元素类型的参数的逗号分隔列表。

在 C# 13 中:

params 修饰符并不局限于数组类型。 现在可以将 params 用于任何已识别的集合类型,包括 System.Span<T>、System.ReadOnlySpan<T>,以及那些实现 System.Collections.Generic.IEnumerable<T> 并具有 Add 方法的类型。 除了具体类型外,还可以使用接口 System.Collections.Generic.IEnumerable<T>、System.Collections.Generic.IReadOnlyCollection<T>、System.Collections.Generic.IReadOnlyList<T>、System.Collections.Generic.ICollection<T>和 System.Collections.Generic.IList<T>

        public static void SpanDataPrintRun()
        {
            Span<int> originalSpan = [1, 2, 3, 4, 5];
            SpanDataPrint(originalSpan);
        }

        public static void SpanDataPrint<T>(params Span<T> spans)
        {
            for (int i = 0; i < spans.Length; i++)
            {
                Console.WriteLine(spans[i]);
            }
        }

新增Lock锁对象

.NET 9 包含一种新的用于互斥的 System.Threading.Lock 类型,比仅在任意 System.Object 实例上进行锁定更有效。该类型通过其 API 提供更好的线程同步,通过Lock.EnterScope()返回的ref struct自动管理锁的释放,减少死锁风险。

        private object _oldLock = new object();
        private System.Threading.Lock _newLock = new System.Threading.Lock();

        public void LockTest()
        {
            lock (_oldLock)
            {
                Console.WriteLine("Old lock");
            }

            lock (_newLock)
            {
                // 传统 lock 语法(优化版)
            }

            using (_newLock.EnterScope())
            {
                //  作用域自动释放(推荐写法)
            }

            _newLock.Enter();
            try
            {
                // 显式 Enter/Exit 调用
            }
            finally { _newLock.Exit(); }

            if (_newLock.TryEnter())
            {
                try
                {
                    // 非阻塞尝试获取锁
                }
                finally { _newLock.Exit(); }
            }

        }

新的转义序列

新增 \e 转义字符作为 ESCAPE 字符 Unicode U+001B 的字符文本转义序列。以前,只能使用的是 \u001b 或 \x1b。不建议使用\x1b,因为如果 1b 后面的下一个字符是有效的十六进制数字,则那些字符会成为转义序列的一部分。

        public static void NewEscapeSequence()
        {
            Console.WriteLine("[31m红色文本[0m");

            // C# 13 之前
            Console.WriteLine("\u001b[31m红色文本\u001b[0m"); //输出红色文字

            // C# 13 中
            Console.WriteLine("\e[31m红色文本\e[0m");//功能相同,语法更简洁
        }

方法组自然类型改进

此功能对涉及方法组的重载解析进行了少量优化。方法组是一个方法,并且所有重载都具有相同的名称。 编译器以前的行为是为方法组构造完整的候选方法集。如果需要自然类型,则自然类型是根据整套候选方法确定的。

  • 详细介绍:https://learn.microsoft.com/zh-cn/dotnet/csharp/language-reference/proposals/csharp-13.0/method-group-natural-type-improvements
// C# 13 中可以直接使用方法组并推断自然类型:
var a = Example.Method; // 成功推断为Action<int>(选择第一个匹配的委托类型)

// 通过上下文进一步优化推断:
List<Action<int>> actions = new() { Example.Method }; // 根据集合类型推断为Action<int>

隐式索引访问

在C# 13中允许在对象初始化表达式中使用^ 运算符(从末尾索引)直接为集合元素赋值。

        public class Numbers
        {
            public int[] Datas { get; set; } = new int[8];
        }

        public static void ImplicitIndexAccess()
        {
            var countdown = new Numbers()
            {
                Datas =
                {
                   [1] = 0,
                   [2] = 1,
                    
                   // 从 C# 13 开始可以执行下面方式赋值
                   [^3] = 2,
                   [^4] = 3,
                   [^5] = 4
                }
            };
        }

异步和迭代器方法中的 ref 与 unsafe 支持

在 C# 13 之前,迭代器方法(使用 yield return 的方法)和 async 方法不能声明局部 ref 变量,也不能使用 unsafe 上下文。

在 C# 13 中,async 方法可以声明 ref 局部变量或 ref struct 类型的局部变量。 但不可跨 await 或 yield return 使用。

同样,C# 13 允许在迭代器方法中使用 unsafe 上下文。但是,所有 yield return 和 yield break 语句都必须在安全的上下文中。

应用场景:提升内存敏感操作(如高性能 Span 处理)的灵活性。

allows ref struct

在 C# 13 之前,ref struct 类型不能声明为泛型或方法的类型参数。现在,泛型类型声明可以添加反约束 allows ref struct。 此反约束声明为该类型参数提供的类型参数可以是 ref struct 类型。编译器会对该类型参数的所有实例执行 ref 安全规则。

  • 应用场景:适用于游戏引擎、实时数据处理等需要低延迟内存操作的领域。通过泛型约束,可编写同时支持 ref struct 和非 ref struct 的通用代码。

例如,可以像下面的代码一样声明一个泛型类型:

public class C<T> where T : allows ref struct
{
    // 使用 T 作为 ref struct:
    public void M(scoped T p)
    {
        //参数 p 必须遵循 ref 安全规则 
    }
}

allows ref struct 反约束声明相应的类型参数可以是 ref struct 类型。 该类型参数的实例必须遵循以下规则:

  • 它不能被装箱。
  • 它参与引用安全规则。
  • 不能在不允许 ref struct 类型的地方使用实例,例如 static 字段。
  • 实例可以使用 scoped 修饰符进行标记。

partial类型中现在允许使用部分属性和索引器

现如今可以在 C# 13 中声明 partial属性partial索引器partial属性和索引器通常遵循与partial方法相同的规则:创建一个定义声明,一个实现声明。这两种声明的签名必须匹配。一个限制是,不能使用自动属性声明来实现部分属性。未声明正文的属性被视为声明声明。

注意:不允许对构造函数、终结器、重载运算符或事件声明使用 partial 关键字。在 C# 13 之前,不允许对属性或索引器使用partial。

public partial class MyClass
{
    public partial string Name { get; set; }
}

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

重载解析优先级

在 C# 13 中,编译器识别 OverloadResolutionPriorityAttribute,以便优先选择一个重载而不是另一个。库作者可以使用该属性确保新的、更好的重载比现有的重载更受青睐。

应用场景:适用于解决特定场景下的重载冲突和性能优化需求。通过合理设置优先级,开发者可以在保持代码兼容性的同时,优化编译器的选择逻辑。

    public class Printer
    {
        [OverloadResolutionPriority(1)] //优先调用
        public static void PrintWay(params int[] numberList) { }

        public static void PrintWay(params ReadOnlySpan<int> numberList) { }
    }

参考文章

C# 13 中的新增功能实操的更多相关文章

  1. ADO.NET 中的新增功能

    ADO.NET 中的新增功能: .NET Framework (current version) 以下是 .NET Framework 4.5 中 ADO.NET 的新增功能. SqlClient D ...

  2. WPF4.5 中的新增功能和增强功能的信息

    本主题包含有关 Windows Presentation Foundation (WPF) 版本 4.5 中的新增功能和增强功能的信息. 本主题包含以下各节: 功能区控件 改善性能,当显示大时设置分组 ...

  3. .NET Framework 4.5、4.5.1 和 4.5.2 中的新增功能

    .NET Framework 4.5.4.5.1 和 4.5.2 中的新增功能 https://msdn.microsoft.com/zh-cn/library/ms171868.aspx

  4. Windows 10 开发人员预览版中的新增功能(转自 IT之家)

    Windows 10 开发人员预览版中的新增功能 在Win10预览版中安装工具与SDK后,即可着手创建Windows通用应用或先浏览目前的环境与此前相比都发生了什么变化. 应用建模 文件资源管理器: ...

  5. C# 中的新增功能

    百度搜索:C# 中的新增功能 微软有站点专门介绍:C# 中的新增功能. 地址:https://docs.microsoft.com/zh-cn/dotnet/csharp/whats-new/inde ...

  6. .NET平台系列14 .NET5中的新增功能

    系列目录     [已更新最新开发文章,点击查看详细] .NET5中不包含的内容 尽管 .NET5 框架中提供了一组重要 API,但它并不包括过去20年左右开发的所有 API,但是.NET Stand ...

  7. 干货 | 京东云应用负载均衡(ALB)多功能实操

    应用负载均衡(Application Load Balancer,简称ALB)是京东云自主研发的一款七层负载均衡产品,主要面向HTTP和HTTPS流量的WEB应用程序,提供灵活的功能配置.应用负载均衡 ...

  8. Java 17 将要发布,补一下 Java 13 中的新功能

    本文章属于Java 新特性教程 系列,已经收录在 Github.com/niumoo/JavaNotes ,点个赞,不迷路. 自从 Oracle 调整了 Java 的版本发布节奏之后,Java 版本发 ...

  9. PHP V5.2 中的新增功能,第 1 部分: 使用新的内存管理器

    PHP V5.2:开始 2006 年 11 月发布了 PHP V5.2,它包括许多新增功能和错误修正.它废止了 5.1 版并被推荐给所有 PHP V5 用户进行升级.我最喜欢的实验室环境 —— Win ...

  10. (译)JavaScript 中的正则表达式(RegEx)实操——快速掌握正则表达式,伴有随手可练的例子————(翻译未完待续)

    (原文:https://blog.bitsrc.io/a-beginners-guide-to-regular-expressions-regex-in-javascript-9c58feb27eb4 ...

随机推荐

  1. 刚学完Vue收集的库或项目分享

    最近刚看完一个Vue3的视频教程,还不错,整理最近收集与Vue相关的库或项目. awesome-vue:与 Vue.js 相关的精彩内容精选清单.https://github.com/vuejs/aw ...

  2. [rustGUI][iced]基于rust的GUI库iced(0.13)的部件学习(01):为窗口设置布局(column、row)

    前言 本文是关于iced库的部件介绍,iced库是基于rust的GUI库,作者自述是受Elm启发. iced目前的版本是0.13.1,相较于此前的0.12版本,有较大改动. 本合集是基于新版本的关于分 ...

  3. Android开发快速入门iOS开发概览

    注:本文同步发布于微信公众号:stringwu的互联网杂谈 Android开发快速入门iOS开发概览 1 前言 笔者总结了自己在拥有Android开发的相关基础后入门iOS开发时遇到的点点滴滴给其他想 ...

  4. SpringBoot(六) - 阿里巴巴的EasyExcel

    1.依赖 <!-- 阿里EasyExcel start --> <dependency> <groupId>com.alibaba</groupId> ...

  5. 直播预览层添加滤镜效果(CIFilter使用场景)

    直播预览层添加滤镜效果 原理,在显示之前,提前对图片进行滤镜处理,把处理后的图片展示出来就好了. CIFiter(滤镜类):给图片添加特殊效果(模糊,高亮等等). CIFiter滤镜分类(一个滤镜可能 ...

  6. Nibbles PG walkthrough Intermediate

    nmap nmap -p- -A 192.168.239.47 Starting Nmap 7.95 ( https://nmap.org ) at 2025-01-15 02:26 UTC Nmap ...

  7. paddle安装中 libssl-1_1-x64.dll 的版本问题

    paddle安装过程中出现的一些问题: 在学习tensorflow过程中,了解到paddlepaddle,本着技多不压身的原则也了解了一下,但是在安装的时候碰到了一些问题.特地记录一下. 一.&quo ...

  8. 小程序uni-app中uview中select选择器第二次无法选中设置的默认值

    <u-select v-model="subjectFlag" title="选择科目" @confirm="okSubjecthander&q ...

  9. 离散最大似然法与 OI

    若总体属于离散型,其分布律在参数 \(\theta\) 作用下 \(P\{X=x\}=p(x;\theta),\Theta=\{\theta\}\) 的形式已知,设 \(X_1,X_2,\dots,x ...

  10. 阿里oos使用

    阿里oss控制台安装 wget http://gosspublic.alicdn.com/ossutil/1.6.17/ossutil64 chmod 755 ossutil64 添加环境变量 cp ...