C# 11 中的新增功能

news/2024/11/8 17:03:57/

我们很高兴地宣布 C# 11 已经发布!与往常一样,C# 开辟了一些全新的领域,同时推进了过去版本中一直在运行的几个主题。我们的文档页面上的 C# 11 的新增功能下有许多功能和详细信息,这些内容都得到了很好的介绍。

随着每个版本的发布,社区的参与度越来越高,他们贡献了从建议、见解和 bug 报告一直到整个功能实现的所有内容。这真的是每个人的C#。谢谢!

UTF-8字符串文字

默认情况下,C# 字符串被硬编码为 UTF-16,而互联网上流行的字符串编码是 UTF-8。为了最大限度地减少转换的麻烦和性能开销,您现在只需将 u8 后缀附加到字符串文字即可立即将它们转换为 UTF-8:

var u8 = "This is a UTF-8 string!"u8;
UTF-8 字符串文字简单地返回一个字节块——以 ReadOnlySpan<byte> 的形式。对于 UTF-8 编码很重要的场景,这可能比某些专用的新 UTF-8 字符串类型更有用。
  • 阅读有关 UTF-8 字符串文字的文档

原始字符串文字

字符串文字中的很多内容都是某种“代码”——不仅是程序文本,还有 JSON 和 XML 数据、HTML、正则表达式、SQL 查询等。当有许多特殊字符在 C# 字符串文字中具有特殊含义时,问题就会显现!值得注意的例子包括 \ 和 ",它们由 { 和 } 连接到内插字符串中。

为什么不采用一种完全没有转义字符的字符串文字形式呢?这就是原始字符串文字。

原始字符串文字至少由三个双引号分隔:

var raw1 = """This\is\all "content"!""";
Console.WriteLine(raw1);

This prints:

This\is\all "content"!

如果您需要三个或更多的“作为内容的一部分,您只需在外部使用更多的”。开头和结尾必须匹配:

var raw2 = """""I can do ", "", """ or even """" double quotes!""""";

这使得粘贴、维护和阅读文字包含的内容变得非常容易。

多行原始字符串文字也可以截断前导空格:结束引号的位置决定了输出中开始包含空格的位置:

var raw3 = """<element attr="content"><body>This line is indented by 4 spaces.</body></element>""";
//  ^white space left of here is removed

由于右引号左侧有四个空格,因此从每行内容的开头删除四个空格,导致以下输出:

<element attr="content"><body>This line is indented by 4 spaces.</body>
</element>

原始字符串文字远不止于此——例如,它们支持字符串内插! 

  • 在文档中阅读有关原始字符串文字的更多信息

对静态成员进行抽象

你如何抽象出本质上是静态的操作——比如运算符?传统的答案是“poorly”。在 C# 11 中,我们发布了对接口中静态虚拟成员的支持,这在 C# 10 中处于预览状态。有了它,您现在可以定义一个非常简单的数学接口:

public interface IMonoid<TSelf> where TSelf : IMonoid<TSelf>
{public static abstract TSelf operator +(TSelf a, TSelf b);public static abstract TSelf Zero { get; }
}

请注意接口如何为“self”获取类型参数。那是因为静态成员没有 this。

现在任何人都可以通过为两个静态成员提供实现并将它们自己作为 TSelf 类型参数传递来实现此接口:

public struct MyInt : IMonoid<MyInt>
{int value;public MyInt(int i) => value = i;public static MyInt operator +(MyInt a, MyInt b) => new MyInt(a.value + b.value);public static MyInt Zero => new MyInt(0);
}

重要的是,您如何使用这些抽象操作?当没有实例可以调用它们时,您如何调用虚拟成员?答案是通过泛型。这是它的样子:

T AddAll<T>(params T[] elements) where T : IMonoid<T>
{T result = T.Zero;foreach (var element in elements){result += element;}return result;
}

类型参数 T 受 IMonoid<T> 接口约束,这允许在 T 本身上调用该接口的静态虚拟成员——Zero 和 +!

现在我们可以用一些 MyInts 调用泛型方法,并通过类型参数传入+ 和 Zero 的正确实现:

MyInt sum = AddAll<MyInt>(new MyInt(3), new MyInt(4), new MyInt(5));

事实上,.NET 7 附带了一个新的命名空间 System.Numerics,其中充满了数学接口,表示您可能想要使用的运算符和其他静态成员的不同组合:IMonoid<T> 的“成熟”版本 接口如上。.NET 中的所有数字类型现在都实现了这些新接口——您也可以将它们添加到您自己的类型中!因此,现在很容易一劳永逸地编写数值算法——从它们处理的具体类型中抽象出来——而不是让大量的重载包含本质上相同的代码。

还值得注意的是,静态虚拟成员对于数学以外的其他事情也很有用。例如,您可以对类型层次结构的工厂方法进行抽象。但我们现在已经涵盖了足够多的内容——您可能想查看文档中关于静态抽象接口方法和泛型数学的这些教程。

即使您不使用静态虚拟成员创建接口,您也可以从现在和将来对 .NET 库所做的改进中受益。

列表模式

模式匹配是 C# 中正在进行的故事之一,我们只是不断地填充它。模式匹配是在 C# 7 中引入的,从那时起它已经发展成为该语言中最重要和最强大的控制结构之一。

C# 11 将列表模式添加到故事中。使用列表模式,您可以递归地将模式应用于类似列表的输入的单个元素——或者它们的范围。让我们直接进入上面的通用算法,使用列表模式重写为递归方法:

T AddAll<T>(params T[] elements) where T : IMonoid<T> =>elements switch
{[] => T.Zero,[var first, ..var rest] => first + AddAll<T>(rest),
};

里面进行了很多事情,但在中心是一个带有两种情况的 switch 表达式。一种情况为空列表 [] 返回零,其中 Zero 由接口定义。另一种情况使用 var first 模式将第一个元素提取到 first 中,然后使用 .. 将剩余元素提取到 rest 中,以将所有剩余元素切出到 var rest 模式中。

  • 在文档中阅读有关列表模式的更多信息。

必需的成员

我们一直致力于多个版本的另一个持续主题是改进对象创建和初始化。C# 11 继续对必需的成员进行这些改进。

在创建使用对象初始值设定项的类型时,您过去无法指定必须初始化某些属性。现在,您可以说属性或字段是必需的。这意味着当创建该类型的对象时,它必须由对象初始值设定项初始化:

public class Person
{
public required string FirstName { get; init; }
public string? MiddleName { get; init; }
public required string LastName { get; init; }
}

现在在没有初始化两个必需属性的情况下创建一个 Person 是错误的:

var person = new Person { FirstName = "Ada" }; // Error: no LastName!
  • 查看文档以获取有关所需成员的更多信息

写在最后

C# 11 还包括许多其他功能。我希望这道“开胃菜”能激发您探索 C# 11 中的新功能,并希望您在使用 C# 11 进行编码时获得与我们编写它时一样多的乐趣!我们努力使语言变得更有用,不仅通过增加更多的表达能力(如静态虚拟成员),而且通过简化、精简和删除样板(如原始字符串文字和列表模式)并使其更安全(如与必需的成员)。

了解 C#11更多新增功能~


http://www.ppmy.cn/news/2057.html

相关文章

数据结构 树练习题

目录 判断 选择 判断 1.一棵有124个结点的完全二叉树&#xff0c;其 叶结点个数是确定的。 【答案】正确 【解析】完全二叉树 若设二叉树的深度为h 除第 h 层外 其它各层 1&#xff5e;(h-1) 的结点数都达到最大个数(即1~(h-1)层为一个满二叉树) 第 h 层所有的结点都连续集…

python 基础之垃圾回收机制

一、背景 之前能说个大概&#xff0c;python垃圾回收机制&#xff0c;设计到细节就不太清楚。 如同刚毕业的少年&#xff0c;出厂自带三年工作经验。做过啥啥.. 一问细节&#xff0c;阿西吧.. 不要问我怎么知道滴.. 哈哈!!!- 提高自己的计算机基础 - 重要的是面试(曾被问到三…

m基于遗传优化的不同等级电动汽车充电站的选址方案matlab仿真

目录 1.算法描述 2.仿真效果预览 3.MATLAB核心程序 4.完整MATLAB 1.算法描述 作为电动汽车的普及与推广&#xff0c;必要的基础配套服务设施、充电站的建设位置和选址规划对整体行业的发展起着重要的意义&#xff0c;本文中提出了一个不同等级电动汽车充电站的选址与求解算…

博士论文答辩流程

2023年夏季毕业 &#xff08;一&#xff09;、总体时间安排 3月10日至3月20日&#xff1a;博士学位论文答辩资格预审 3月20日至3月25日&#xff1a;提交博士学位论文截止时间&#xff0c;评审时限为30天&#xff08;学院学籍的截止时间为3月20日&#xff09; 4月5日&#xf…

私人定制AI绘画——快速finetune stable diffusion教程

最近AI绘图非常火&#xff0c;只需要输入文本就能得到令人惊艳的图。 举个例子&#xff0c;输入 “very complex hyper-maximalist overdetailed cinematic tribal darkfantasy closeup portrait of a malignant beautiful young dragon queen goddess megan fox with long bl…

CSS盒子模型

网页布局过程&#xff1a; 1&#xff1a;准备好相关的网页元素&#xff0c;也就是大大小小的盒子2&#xff1a;利用CSS设置好盒子样式&#xff0c;将对不同的盒子摆放到对应的位置3&#xff1a;将内容填充到对应的盒子中盒子模型&#xff1a; 将html页面中的布局元素看作是一…

面向碳中和的公共建筑室内环境营造再认识

3月26日&#xff5c;清华大学建筑节能学术周——公共建筑节能—工程实践助力实现双碳目标 【3月26日公开论坛】公共建筑节能 – 工程实践助力实现双碳目标 面向碳中和的公共建筑室内环境营造再认识 对“舒适”、“健康”和室内环境营造手段的再认识 1.对“舒适”的再认识 P…

Linux——Xshell、Xftp实现Linux远程登录与应用

目录 一、远程登录 1.1 SSH登录方式 二、Xshell远程连接 2.1 远程连接 2.2 设置粘贴复制 三、Xftp远程连接 3.1 远程连接 3.2 解决乱码 3.3 传输文件 一、远程登录 通常在工作过程中&#xff0c;公司中使用的真实服务器或者是云服务器&#xff0c;都不允许除运维人员 之…