当前位置: 首页 > news >正文

C# 12 预览版的新功能

作者:Kathleen Dollard
排版:Alan Wang

Visual Studio 17.7 Preview 3 和 .NET 8 Preview 6 的发布推进了 C# 12的发展。此预览版包含的功能为将来的性能增强奠定了基础。现在,您能够在库中更方便的使用内联函数。此预览版首次推出了一项实验性功能:拦截器。该功能允许生成器重新路由代码,例如提供特定于上下文的优化。最后,nameof 功能得到增强,您可以在更多的地方使用它。

安装最新的 Visual Studio 预览版或最新版本的 .NET SDK 来使用 C# 12 。将项目的语言版本设置为 preview,就可查看 C# 12 的功能:

<PropertyGroup><LangVersion>preview</LangVersion>
</PropertyGroup>

由于这是实验性的功能,所以拦截器需要在项目文件中添加一个附加标志。

nameof 访问实例成员

nameof 关键字现在可用于成员名称,如初始化器、静态成员以及属性:

internal class NameOf
{public string S { get; } = "";public static int StaticField;public string NameOfLength { get; } = nameof(S.Length);public static void NameOfExamples(){Console.WriteLine(nameof(S.Length));Console.WriteLine(nameof(StaticField.MinValue));}[Description($"String {nameof(S.Length)}")]public int StringLength(string s){ return s.Length; }
}

您可以在 C# 12 的新增功能中了解更多信息。

内联数组

InlineArrayAttribute 是在以前的 .NET 8 预览版中引入到运行时的。 这是一项高级功能,主要由编译器、.NET 库和其他一些库使用。 该属性标识了一种可被视为连续基元序列的类型,以实现高效、类型安全、越界安全的可索引/可切分内联数据。 .NET 库使用内联数组提高应用程序和工具的性能。

编译器创建不同的 IL 来访问内联数组。 这会导致一些限制,例如不支持列表模式。 在大多数情况下,您可以像访问其他数组一样访问内联数组。 不同的 IL 可以在不更改代码的情况下提高性能:

private static void InlineArrayAccess(Buffer10<int> inlineArray)
{for (int i = 0; i < 10; i++){inlineArray[i] = i * i;}foreach (int i in inlineArray){Console.WriteLine(i);}
}

对于内联数组,大多数人倾向于使用,而不是创建。 但是,了解事物的运作方式大有裨益。 内联数组速度很快,因为它们依赖于指定长度的精确布局。 内联数组是一种具有单个字段的类型,并用指定数组长度的 InlineArrayAttribute 进行标记。 在上一个示例中使用的类型中,由于属性参数,运行时会在 Buffer10<T> 中为10个元素创建存储空间:

[System.Runtime.CompilerServices.InlineArray(10)]
public struct Buffer10<T>
{private T _element0;
}

您可以在 C# 12的新增功能中了解更多信息。

拦截器

此预览版引入了一项名为拦截器的实验性功能。它适用于一些高级场景,特别是允许更好的提前编译(AOT)。作为 .NET 8 的实验部分,在未来版本中它可能会被更改或删除。因此,先不要在生产中使用这项功能。

拦截器允许将特定方法调用重新路由到不同的代码。属性指定实际的源代码位置,因此拦截器通常仅适用于源生成器。您可以阅读拦截器提案以了解有关拦截器如何工作的更多信息。

由于拦截器是一项实验性功能,因此您需要在项目文件中显式启用它们:

<PropertyGroup><Features>InterceptorsPreview</Features>
</PropertyGroup>

拦截器可以实现绝佳的代码模式。以下是一些例子:

  • 可以拦截编译时已知的调用,例如具有常量模式的 Regex.IsMatch(@"a+b+"),并使用静态生成的代码进行优化,以便更好地适用于提前编译(AOT)环境 。
  • 可以拦截诸如 app.MapGet("/products", handler: (int? page, int? pageLength, MyDb db) => { ... }) 之类的 ASP.NET Minimal API 调用来注册一个静态生成的 thunk,该 thunk 会直接调用用户的处理程序,从而跳过分配和间接。
  • 在矢量化中,foreach 循环包含对用户方法的调用,编译器可以重写代码以在运行时检查和使用相关的内部函数,但如果这些内部函数不可用,则返回到原始代码。
  • 依赖注入的静态依赖图解析,其中 provider.Register<MyService>() 可以被拦截。
  • 可以拦截对查询提供程序的调用,以在编译时提供对另一种语言(例如 SQL)的翻译,而不是评估表达式树以在运行时进行翻译。
  • 序列化器可以根据具体的调用类型(如 Serialize<MyType>())生成特定于类型的(反)序列化,所有这些都在编译时进行。

虽然大多数程序员不会直接使用拦截器,但我们仍希望它能够在开发中发挥重要作用,使您的应用程序更快运行并更易部署。拦截器预计在 C# 12/.NET 8 版本中仍保持实验阶段,并可能包含在 C# 的后续版本中。

总结

您可以在 Microsoft Learn 的 C# 12 新增功能页面上找到有关迄今为止引入的所有功能的更多信息,并在 Roslyn 功能状态页面上跟踪 C# 12 功能的演变。

您可以通过下载最新的 Visual Studio 预览版或最新版本的 .NET SDK 并在您的项目文件中将 LangVersion 设置 preview 来查看最新的 C# 12 功能。

请让我们知道您的想法!

http://www.lryc.cn/news/108833.html

相关文章:

  • 34.利用matlab解 多变量多目标规划问题(matlab程序)
  • 暑假刷题第18天--7/30
  • 通向架构师的道路之Apache整合Tomcat
  • 如何消除“信息孤岛”对业务增长的威胁?
  • Kali部署dvwa和pikachu靶场
  • ​LeetCode解法汇总722. 删除注释
  • Linux中的firewall-cmd
  • python 最大归一化
  • Netty:ByteBuf写入数据、读出数据
  • C++(15):面向对象程序设计
  • 2023牛客暑期多校训练营6-A Tree
  • Vc - Qt - QPainter::SmoothPixmapTransform及QPainter::Antialiasing
  • 【练习】条件变量:创建三个线程 id号为ABC,三个线程循环打印自己的ID号,运行顺序为 ABCABC
  • SpringBoot项目修改中静态资源,只需刷新页面无需重启项目(附赠—热加载)
  • clear_data_code_2d_model
  • “深入剖析JVM:揭秘Java虚拟机的工作原理“
  • elementui表格table中实现内容的换行
  • java 框架
  • 死锁的发生原因和怎么避免
  • visual studio 生成dll文件以及修改输出dll文件名称操作
  • 【Leetcode】73.矩阵置零
  • zabbix监控mysql容器主从同步状态并告警钉钉/企业微信
  • ARM 常见汇编指令学习 9 - 缓存管理指令 DC 与 IC
  • 落地数字化管理,提升企业市场竞争力
  • 2023华数杯数学建模竞赛C题思路解析
  • Photon之如何解决Photon Server无法在局域网使用的bug
  • Redis两种持久化方案RDB持久化和AOF持久化
  • 银河麒麟v10 vnc环境配置
  • 【动态内存管理助力程序优化与性能飞升】
  • 电动汽车设计、制造、研发的学科、技术和前沿科技综述