.NET9 - 新功能体验(二)
书接上回,我们继续来聊聊.NET9和C#13带来的新变化。

01、新的泛型约束 allows ref struct
这是在 C# 13 中,引入的一项新的泛型约束功能,允许对泛型类型参数应用 ref struct 约束。
可能这样说不够直观,简单来说就是Span、ReadOnlySpan类型,我们直接看下面的代码示例:

在没有新的约束allows ref struct之前,Span是不能当参数传入的,直接编译错误,但是有了新约束则就可以支持Span参数了。
因此C# 13 中引入了 where T : allows ref struct 泛型约束后使得我们可以对泛型参数类型进行更加精细的控制。通过这个特性,泛型方法或类就可以接受 ref struct 类型,如 Span 、ReadOnlySpan等,因为这些类型是在栈上分配内存,能够提供更高效的内存管理和更快的执行速度,所以这个新特性特别适用于高性能、内存密集型的泛型方法和类,可以有效避免堆分配和垃圾回收的开销。
02、ref struct接口
在 C# 13 之前,ref struct 是无法实现接口的。 从 C# 13 开始,ref struct可实现接口,但必须遵循 ref 安全性规则。 例如,由于需要装箱转换,因此无法将 ref struct 类型转换为接口类型。

如上图,ref struct类型可以实现IInterface接口,但是当用IInterface接口去接收RefStructInterface类型时则直接编译报错,无论直接接收还是强制转换都是不支持的。
03、在异步方法中使用ref struct
从C# 13开始,ref struct可以在异步方法中使用,但是有一个限制:它们不能在与 await 表达式同一个代码块中交互。这是为了避免 ref struct在跨越异步操作时引发内存安全问题,因为 ref struct 类型的实例通常存储在栈上,并且不能在异步操作中跨越栈帧。
下面代码是在异步方法中使用ref struct示例:
ref int Process(ref int x)
{
    return ref x;
}
//在异步方法中使用ref
async Task RefInAsync()
{
    var value = 0;
    await Task.Delay(0);
    ref var local = ref Process(ref value);
}
04、在迭代器中使用ref struct
从 C# 13 开始,允许在迭代器方法中使用 ref struct,前提是满足以下条件:不能在包含 yield return 的代码段中使用它们。这是因为yield return 语句会导致方法的执行暂停并在以后继续执行。如果在这期间使用了ref struct,可能会导致这些类型的生命周期管理出现问题(例如跨越栈帧的切换)。为了避免这种问题,C# 13 规定,如果要在迭代器方法中使用 ref struct,则不能在 yield return 语句所在的代码段中操作它们。
下面是在迭代器中使用ref struct示例代码:
ref int Process(ref int x)
{
    return ref x;
}
//在迭代器中使用ref
IEnumerable<int> RefInIterator(int[] array)
{
    for (var i = 0; i < array.Length; i++)
    {
        ref var v = ref Process(ref array[i]);
        yield return v;
    }
}
05、部分属性、部分索引器
早在C#2就引入了部分类,在C#3引入了部分方法,到现在C#13又新增了部分属性和部分索引器。
这一改进这意味着允许属性和索引器可以跨越多个部分进行声明和实现。这给自动生成代码或分离关注点带来了极大便利,也更加灵活地生成和管理属性代码,特别适用于与源代码生成器等工具结合使用的场景。
以下是 C# 13 中属性支持partial的示例:
public partial class PartialExamples
{
    //部分属性
    public partial int Capacity { get; set; }
    //部分索引器
    public partial string this[int index] { get; set; }
    //部分方法
    public partial string? TryGetItemAt(int index);
}
public partial class PartialExamples
{
    private List<string> _items = ["one", "two", "three", "four", "five"];
    //部分属性
    public partial int Capacity
    {
        get => _items.Count;
        set
        {
            if ((value != _items.Count) && (value >= 0))
            {
                _items.Capacity = value;
            }
        }
    }
    //部分索引器
    public partial string this[int index]
    {
        get => _items[index];
        set => _items[index] = value;
    }
    //部分方法
    public partial string? TryGetItemAt(int index)
    {
        if (index < _items.Count)
        {
            return _items[index];
        }
        return null;
    }
}
06、foreach 支持Index
相信很多人都遇到过想要在foreach的时候获取集合元素当前索引,一般两种选择,一种自己维护一个变量,一种直接改用for。
而.NET9开始总算改变了这一现状,可以在foreach时候同时获取到当前元素及其索引。
我们下面看看Index()方法给我们带来了多大便利,代码如下:
//.NET 9 之前
 public void Loop()
 {
     List<string> items = ["张三", "李四", "王五"];
     var idx = 0;
     foreach (var item in items)
     {
         idx++;
         Console.WriteLine($"第{idx}个人名字是:{item}");
     }
 }
 //.NET 9
 public void LoopNew()
 {
     List<string> items = ["张三", "李四", "王五"];
     //直接获取索引、元素
     foreach ((int Index, string Item) in items.Index())
     {
         Console.WriteLine($"第{Index + 1}个人名字是:{Item}");
     }
 }
 //.NET 9
 public void LoopNew2()
 {
     List<string> items = ["张三", "李四", "王五"];
     //先获取元组后,再获取索引、元素
     foreach (var item in items.Index())
     {
         Console.WriteLine($"第{item.Index + 1}个人名字是:{item.Item}");
     }
 }
注:测试方法代码以及示例源码都已经上传至代码库,有兴趣的可以看看。https://gitee.com/hugogoos/Planner
.NET9 - 新功能体验(二)的更多相关文章
- VS2017十五项新功能体验
		Visual Studio 2017十五项新功能体验 Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP ... 
- Visual Studio 2017十五项新功能体验
		Visual Studio 2017正式已经于2017.3.7号正式发布,选在这一天发布也是为了纪念Visual Studio 二十周年.MVP 2017技术峰会将于这个周末(3.17)在北京举办,由 ... 
- VS2015预览版中的C#6.0 新功能(二)
		VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(三) 自动属性的增强 只读自动属性 以前自动属性必须同时提供setter和getter方法,因而只读属性只能通 ... 
- MWeb 1.4 新功能介绍二:静态博客功能增强
		MWeb 比较有特色的是一键生成静态博客功能,然后从 MWeb 最开始规划要做静态博客生成功能时,我就希望 MWeb 的静态博客生成功能在易用的同时,还要有很强大的扩展性. 比如说能自己增加网站公告, ... 
- 最新版Swagger 3升级指南和新功能体验!
		Swagger 3.0 发布已经有一段时间了,它于 2020.7 月 发布,但目前市面上使用的主流版本还是 Swagger 2.X 版本和少量的 1.X 版本,然而作为一名合格的程序员怎么能不折腾新技 ... 
- VS2015预览版中的C#6.0 新功能(三)
		VS2015预览版中的C#6.0 新功能(一) VS2015预览版中的C#6.0 新功能(二) Using static 使用using StaticClass,你可以访问StaticClass类里的 ... 
- VS2015预览版中的C#6.0 新功能(一)
		VS2015预览版中的C#6.0 新功能(二) VS2015预览版中的C#6.0 新功能(三) VS2015的预览版在11月12日发布了,下面让我们来看看C#都提供了哪些新的功能. 字符串添写(Str ... 
- CRM 2013 系统设置新功能二:Entity images  图像字段
		CRM2013系统默认的许多实体都已经有了图像的选择,如 右上角可以设置当前用户的头像. 客户.联系人等都可以,下面将介绍一下此项新功能: 一.实体中新建图像字段,其中系统自动命名entityinag ... 
- 个人官网第8次升级(新功能、用户体验、修复bug、系统优化)
		1.新功能. 操作日志和搜索日志的Excel报表下载. 2.用户体验. 如果是通过搜索,进入到一篇内容, 搜索关键词需要高亮. 比如,搜索"程序员"出现若干内容链接,打开链接的页面 ... 
- 地图SDK全面升级 – 数十项新功能及优化等你来体验
		腾讯位置服务地图SDK是一套提供多种地理位置服务的应用程序接口.通过调用该接口,开发者可以在自己的应用中加入地图相关的功能(如地图展示.标注.绘制图形等),轻松访问腾讯地图服务和数据,构建功能丰富.交 ... 
随机推荐
- 深度解析HarmonyOS SDK实况窗服务源码,Get不同场景下的多种模板
			HarmonyOS SDK实况窗服务(Live View Kit)作为一个实时呈现应用服务信息变化的小窗口,遍布于设备的各个使用界面,它的魅力在于将复杂的应用场景信息简洁提炼并实时刷新,在不影响当前其 ... 
- 【Python自动化】之利用JS操作页面滚动条(新)
			如何操作页面中的滚动条,有以下几个方法: 一.查找可见元素进行滚动页面(通用) 方法一: ①移动到元素element对象的"顶端",与当前窗口的"顶部"对齐(默 ... 
- Python自动复制Excel数据:将各行分别重复指定次数
			本文介绍基于Python语言,读取Excel表格文件数据,并将其中符合我们特定要求的那一行加以复制指定的次数,而不符合要求的那一行则不复制:并将所得结果保存为新的Excel表格文件的方法. 这 ... 
- 【YashanDB知识库】字段加上索引后,SQL查询不到结果
			[标题]字段加上索引后,SQL查询不到结果 [问题分类]索引功能使用 [关键字]索引,SQL查询,时间类型,vachar字符类型 [问题描述]字段加上索引后,SQL查询不到结果. [问题原因分析]当前 ... 
- Python存储与读写二进制文件
			技术背景 一般情况下我们会选择使用明文形式来存储数据,如json.txt.csv等等.如果是需要压缩率较高的存储格式,还可以选择使用hdf5或者npz等格式.还有一种比较紧凑的数据存储格式,就是直接按 ... 
- Go实现常用的排序算法
			一.插入排序 1.从第一个元素开始,该元素可以认为已经被排序 2.取出下一个元素,在已经排序的元素序列中从后向前扫描 3.如果该元素(已排序)大于新元素,将该元素移到下一位置 4.重复步骤3,直到找到 ... 
- 软件测试之Docker常见问题汇总!附解决方法!
			1.配置国内源进行docker安装,报错 HTTP Error 404 - Not Found 原因: 由于配置国内镜像源时,把地址写错了,导致后面安装docker提示HTTP Error 404 解 ... 
- 如何使用Java在Word中插入表格
			序言 各位好啊,我是会编程的蜗牛,作为java开发者,有时候需要操作word或者excel.这里面比较常用的框架是POI,我之前用过POI来读写excel,也有用过alibaba easy excel ... 
- 实用技巧:根据menuconfig定位一个驱动涉及到的源文件
			根据menuconfig定位一个驱动涉及到的源文件,这个是很常用的,因为有时候你需要参考别人的驱动代码.新手不知道如何定位驱动相关源码,这篇文章将告之. 假设我手头有一块开发板,现在我想要获取板载ov ... 
- "放开那代码让我来!"——Cursor帮你写代码的奇妙之旅
			让我们开门见山:编程很酷,但也很折磨人.那些长时间盯着屏幕,debug无休止的日子,只有程序员懂得它的酸爽.而就在这个编程焦虑的世界中,Cursor横空出世,带着一系列魔法功能,如同你手中的一根智能魔 ... 
