C# 12 中新增的八大功能你都知道吗?
前言
转眼之间C#都已经更新到了12了,那么C# 12 中新增的八大功能你都了解过吗?今天我们来简单介绍一下C# 12 中新增的八大功能。
- C#/.NET该如何自学入门?:https://www.cnblogs.com/Can-daydayup/p/18006914
- C#12详细功能介绍请阅读微软官方文档:https://learn.microsoft.com/zh-cn/dotnet/csharp/whats-new/csharp-12
同学们可以使用最新的 Visual Studio 2022 版本或 .NET 8 SDK 尝试这些功能。
一、主构造函数
在 Visual Studio 2022 版本 17.6 预览版 2 中引入。
从 C# 12 开始,可以在类和结构中声明主构造函数。主构造函数参数都在类的整个主体的范围内。为了确保显式分配所有主构造函数参数,所有显式声明的构造函数都必须使用 this() 语法调用主构造函数。将主构造函数添加到 class 可防止编译器声明隐式无参数构造函数。在 struct 中,隐式无参数构造函数初始化所有字段,包括 0 位模式的主构造函数参数。
主构造函数参数的最常见用途包括:
- 作为 base() 构造函数调用的参数。
- 初始化成员字段或属性。
- 引用实例成员中的构造函数参数。
代码示例
将任何参数放在类型名称后面的括号中:
public class NameParameter(string name)
{
public string Name => name;
}
以下代码初始化从主构造函数参数计算的两个只读属性:
public readonly struct Distance(double dx, double dy)
{
public readonly double Magnitude { get; } = Math.Sqrt(dx * dx + dy * dy);
public readonly double Direction { get; } = Math.Atan2(dy, dx);
}
二、集合表达式
在 Visual Studio 2022 版本 17.7 预览版 5 中引入。
集合表达式引入了一种新的简洁语法,用于创建常用集合值。可以使用展开运算符(..)将其他集合内联到这些值中。
下面的示例展示了集合表达式的用法:
// Create an array
int[] array = [55, 99, 100, 33];
// Create a list
List<string> list = ["one", "two", "three", "five", "追逐时光者"];
// Create a span
Span<char> c = ['a', 'b', 'c', 'd', 'e', 'f', 'h', 'i', 'k'];
// Create a jagged 2D array
int[][] two2D = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [88, 8, 9]];
展开运算符(..)示例代码:
展开运算符(集合表达式中的 ..)可将其参数替换为该集合中的元素。参数必须是集合类型。以下示例演示了展开运算符的工作原理:
int[] item0 = [88, 2, 3];
int[] item1 = [22, 5, 6];
int[] item2 = [7, 99, 9];
int[] single = [.. item0, .. item1, .. item2];
foreach (var element in single)
{
Console.Write($"{element}, ");
}
没有.. 会有异常:

正常输出:

三、内联数组
在 Visual Studio 2022 版本 17.7 预览版 3 中引入。
运行时团队和其他库作者使用内联数组来提高应用程序的性能。通过内联数组,开发人员可以在结构类型中创建固定大小的数组。具有内联缓冲区的结构体应具有与不安全固定大小缓冲区类似的性能特性。
内联数组的声明与下面的结构类似:
[System.Runtime.CompilerServices.InlineArray(20)]
public struct Buffer
{
private int _element0;
}
你可以像使用其他数组一样使用它们:
public static void Test()
{
var buffer = new Buffer();
for (int i = 0; i < 20; i++)
{
buffer[i] = i;
}
foreach (var i in buffer)
{
Console.WriteLine(i);
}
}
四、Lambda 表达式中的可选参数
在 Visual Studio 2022 版本 17.5 预览版 2 中引入。
可以为 Lambda 表达式的参数定义默认值。语法和规则与将参数的默认值添加到任何方法或本地函数相同。
如果 lambda 表达式只有一个输入参数,则括号是可选的:
Func<double, double> cube = x => x * x * x;
两个或更多输入参数使用逗号加以分隔:
Func<int, int, bool> testForEquality = (x, y) => x == y;
可以显式指定类型,如下面的示例所示:
注意:输入参数类型必须全部为显式或全部为隐式;否则,便会生成 CS0748 编译器错误!!
Func<int, string, bool> isTooLong = (int x, string s) => s.Length > x;
五、ref readonly参数
在 Visual Studio 2022 版本 17.8 预览版 2 中引入。
ref readonly修饰符表示方法希望参数是一个变量,而不是一个非变量的表达式。不是变量的表达式包括常量、方法返回值和属性。如果参数不是变量,编译器会发出警告。
六、任何类型的别名
在 Visual Studio 2022 版本 17.6 预览版 3 中引入。
可以使用 using alias 指令来别名任何类型,而不仅仅是命名类型。也就是说,你可以为元组类型、数组类型、指针类型或其他不安全类型创建语义别名。
使用 using 关键字为元组类型创建别名,并进行调用:
using PointTest = (int x, int y);
namespace Csharp12
{
internal class Class1
{
public static void Test()
{
PointTest point = (10, 20);
Console.WriteLine($"Point coordinates: X={point.Item1}, Y={point.Item2}");
}
}
}
七、Experimental属性
在 Visual Studio 2022 版本 17.7 预览版 3 中引入。
- 可以使用 System.Diagnostics.CodeAnalysis.ExperimentalAttribute 来标记类型、方法或程序集,以指示实验性特征。如果访问使用 ExperimentalAttribute 注释的方法或类型,编译器将发出警告。用 Experimental 特性标记的程序集中包含的所有类型都是实验性的。
示例代码:
namespace Csharp12
{
[AttributeUsage(System.AttributeTargets.Assembly | System.AttributeTargets.Class | System.AttributeTargets.Constructor | System.AttributeTargets.Delegate | System.AttributeTargets.Enum | System.AttributeTargets.Event | System.AttributeTargets.Field | System.AttributeTargets.Interface | System.AttributeTargets.Method | System.AttributeTargets.Module | System.AttributeTargets.Property | System.AttributeTargets.Struct)]
public class ExperimentalAttribute : Attribute
{
public ExperimentalAttribute()
{
}
}
[Experimental]
public class ExperimentalClass
{
public void DoSomething()
{
Console.WriteLine("Doing something experimental...");
}
}
internal class Class1
{
public static void Test()
{
ExperimentalClass exp = new ExperimentalClass();
exp.DoSomething();
}
}
}
八、拦截器
预览功能在 Visual Studio 2022 版本 17.7 预览版 3 中引入。
拦截器是一种方法,该方法可以在编译时以声明方式将对可拦截方法的调用替换为对其自身的调用。通过让拦截器声明所拦截调用的源位置,可以进行这种替换。拦截器可以向编译中(例如在源生成器中)添加新代码,从而提供更改现有代码语义的有限能力。
注意:拦截器是一项试验性功能,在 C# 12 的预览模式下提供。在将来的版本中,该功能可能会发生中断性变更或被删除。因此,不建议将其用于生产或已发布的应用程序。
要使用拦截器,用户项目必须指定 <InterceptorsPreviewNamespaces> 属性。这是允许包含拦截器的命名空间列表。
<InterceptorsPreviewNamespaces>$(InterceptorsPreviewNamespaces);Microsoft.AspNetCore.Http.Generated;MyLibrary.Generated</InterceptorsPreviewNamespaces>
DotNetGuide技术社区交流群
- DotNetGuide技术社区是一个面向.NET开发者的开源技术社区,旨在为开发者们提供全面的C#/.NET/.NET Core相关学习资料、技术分享和咨询、项目推荐、招聘资讯和解决问题的平台。
- 在这个社区中,开发者们可以分享自己的技术文章、项目经验、遇到的疑难技术问题以及解决方案,并且还有机会结识志同道合的开发者。
- 我们致力于构建一个积极向上、和谐友善的.NET技术交流平台,为广大.NET开发者带来更多的价值和成长机会。
C# 12 中新增的八大功能你都知道吗?的更多相关文章
- Oracle12.2中新增的分区功能
Oracle 12.2已经发布一段时间,公网上也可以下载试用.针对12.2,partitioning(分区)也有了不少增强. 自动列表分区 多字段列表分区 只读分区 分区维护时允许过滤 在线转换非分区 ...
- ASP.Net4.0中新增23项功能
这篇文章介绍Visual Studio 2010 (ASP.Net 4.0)的新功能. 1.代码片段(Code Snippets): 代码段是预先开发的代码模板,可以节省我们对有关语法思考的时间.在V ...
- NET Framework 4 中的新 C# 功能
http://msdn.microsoft.com/zh-cn/magazine/ff796223.aspx C# 编程语言自 2002 年初次发布以来已经有了极大的改善,可以帮助程序员编写更清晰易懂 ...
- MySQL5.6中新增特性、不推荐使用的功能以及废弃的功能
虽然已经使用MySQL5.6版本有一段时间了,但由于没有和之前的版本作过详细比较,所以对于哪些重要的或者不太重要的特性是在新版本中引入的,还有哪些特性已经或者将要从旧版本中移除的并没有一个十分全面的了 ...
- 妙味css3课程---1-2、css3中新增的伪类和伪元素有哪些
妙味css3课程---1-2.css3中新增的伪类和伪元素有哪些 一.总结 一句话总结: 1.div:target{}是什么意思? 比如a标签的锚点链接到div,div:target{}就可以找到这个 ...
- html5中新增的元素和废除的元素
一.新增的结构元素 1.section元素表示页面中的一个内容区块,比如章节.页眉.页脚或页面中的其他部分.它可以与h1.h2.h3.h4.h5.h6等元素结合起来使用,标示文档结构. h5中的代码事 ...
- Java第十二次作业:什么是一维数组?什么是对象数组?吃金币游戏2.0版 新增炸弹功能 新增游戏倒计时功能 新增胜利失败检测功能 使用如鹏游戏引擎制作窗体 一维数组设置金币
什么是数组? 数组的定义:是用统一的名字代表这批数据,用序号来区分各个数据.数组是无序的数据元素按有序的下标组成的集合,分配固定空间大小的一种容器. 如何理解:其实就是一个同时放很多数据的变量. a= ...
- ABBYY FineReader 15新增编辑页面布局功能
ABBYY FineReader 15(Windows系统) 新增编辑页面布局功能,允许用户修改PDF数字文档的页面布局,包括添加或者删除文字段落,文字块以及图片,更改段落,文字块,图片位置.添加或者 ...
- html5中新增的form表单属性
html5中新增两个表单属性,分别autocomplete和novalidate属性 1.autocomplete属性 该属性用于控制自动完成功能的开启和关闭.可以设置表单或者input元素,有两个属 ...
- 禁用datagridview中的自动排序功能
把datagridview中的自动排序功能禁用自己收集的两种方法,看看吧①DataGridView中的Columns属性里面可以设置.进入"EditColumns"窗口后,在相应的 ...
随机推荐
- C++初始化列表时,形参和实参名可以一样,编译器可以识别
在这里初始化列表直接用age(age)即可,用this->age(age)反而会出错,C++不允许在成员初始化列表中使用this关键字来初始化类成员 class Person { public: ...
- SpringBoot实现限流注解
SpringBoot实现限流注解 在高并发系统中,保护系统的三种方式分别为:缓存,降级和限流. 限流的目的是通过对并发访问请求进行限速或者一个时间窗口内的的请求数量进行限速来保护系统,一旦达到限制速率 ...
- 使用requests爬虫遇到的一个奇葩的问题:UnicodeEncodeError: 'latin-1' codec can't encode character
每一位成功的程序员,背后也许都站着无数的秃头的男人--为其提供各种开发工具&代码库,当然也包括-- 各种玄学bug-- 玄学的开端 最近在用Python做一个爬虫项目的时候遇到一个很奇怪的问题 ...
- 关于JVM指针压缩性能的研究
关于JVM指针压缩性能的研究 摘要 JVM的内存对消最小是 8bytes 所以32G内存的情况下可以使用 32位的指针就可以了. 32位就是4G 在乘以最小的内存extent 8 bytes 的出来可 ...
- [转帖]SQL Server JDBC – Set sendStringParametersAsUnicode to false
https://vladmihalcea.com/sql-server-jdbc-sendstringparametersasunicode/ https://learn.microsoft.com/ ...
- Harbor简单搭建以及异常排查的过程与思路
Harbor简单搭建以及异常排查的过程与思路 前言 我发现我总是能够遇到别人遇不到的问题. 本来搭建十分钟就可以搭建完成 结果我硬生生的搭建了四十分钟. 为了保证下次不再浪费时间. 这里加单总结一下遇 ...
- echarts给每个柱状图配置不同的颜色
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title> ...
- 手写promise完成异常处理和状态只能够修改一次
8.处理 Promise 抛出的异常 <script src="./Promise.js"></script> <script type=" ...
- 每日一道Java面试题:Java是值传递还是引用传递?
写在开头 Java是值传递还是引用传递?这个问题几乎100%的出现在了各大主流Java面试题中,知识点很小,但很考验面试者对于Java运行的理解,今晚趁着生产投产的空子,过来小聊一下. 实参与形参 所 ...
- Go基础之指针
Go语言中的指针 目录 Go语言中的指针 一.Go语言中的指针介绍 1.1 指针介绍 1.2 基本语法 1.3 声明和初始化 1.4 Go 指针的3个重要概念 1.4.1 指针地址(Pointer A ...