【译】C# 11 特性的早期预览
原文 | Kathleen
翻译 | 郑子铭
Visual Studio 17.1(Visual Studio 2022 Update 1)和 .NET SDK 6.0.200 包含 C# 11 的预览功能!您可以更新 Visual Studio 或下载最新的 .NET SDK 来获得这些功能。
查看帖子 Visual Studio 2022 17.1 现已推出!了解 Visual Studio 中的新增功能和发布 .NET 7 Preview 1 的帖子以了解更多 .NET 7 预览功能。
设计 C# 11
我们喜欢公开设计和开发!您可以在 CSharpLang 存储库中找到有关未来 C# 功能的建议和语言设计会议的注释。主页解释了我们的设计过程,您可以在 .NET Community Runtime and Languages Standup 上收听 Mads Torgersen,他在其中谈到了设计过程。
一旦计划好某个功能的工作,工作和跟踪就会转移到 Roslyn 存储库。您可以在功能状态页面上找到即将推出的功能的状态。您可以看到我们正在进行的工作以及合并到每个预览中的内容。您还可以回顾以前的版本以检查您可能忽略的功能。
在这篇文章中,我将这些有时是复杂的技术性讨论提炼成代码中每个特性的含义。
我们希望您能试用这些新的预览功能,并让我们知道您的想法。要试用 C# 11 预览功能,请创建一个 C# 项目并将 LangVersion 设置为 Preview。您的 .csproj 文件可能如下所示:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>preview</LangVersion>
</PropertyGroup>
</Project>
C# 11 预览:允许在插值字符串的“孔”中换行
在提案中阅读有关此更改的更多信息,删除非逐字插值字符串中的插值不能包含换行符的限制。 #4935
C# 支持两种类型的内插字符串:逐字和非逐字内插字符串(分别为 $@"" 和 $"")。它们之间的一个关键区别是非逐字插值字符串不能在其文本段中包含换行符,而必须使用转义符(如 \r\n)。逐字插值字符串可以在其文本段中包含换行符,并且不会转义换行符或其他字符(除了“”来转义引号本身)。所有这些行为保持不变。
以前,这些限制扩展到非逐字插值字符串的孔。孔是表示插值表达式的简写方式,是花括号内提供运行时值的部分。孔本身不是文本,不应遵守内插字符串文本段的转义/换行规则。
例如,以下内容会导致 C# 10 中的编译器错误,并且在此 C# 11 预览版中是合法的:
var v = $"Count ist: { this.Is.Really.Something()
.That.I.Should(
be + able)[
to.Wrap()] }.";
C# 11 预览:列表模式
阅读更多关于提案列表模式中的这种变化。
新的列表模式允许您匹配列表和数组。您可以匹配元素,并且可以选择包含匹配零个或多个元素的切片模式。使用切片模式,您可以丢弃或捕获零个或多个元素。
列表模式的语法是方括号括起来的值,切片模式是两个点。切片模式后面可以跟另一个列表模式,例如 var 模式来捕获切片的内容。
模式 [1, 2, .., 10] 匹配以下所有内容:
int[] arr1 = { 1, 2, 10 };
int[] arr1 = { 1, 2, 5, 10 };
int[] arr1 = { 1, 2, 5, 6, 7, 8, 9, 10 };
要探索列表模式,请考虑:
public static int CheckSwitch(int[] values)
=> values switch
{
[1, 2, .., 10] => 1,
[1, 2] => 2,
[1, _] => 3,
[1, ..] => 4,
[..] => 50
};
当它传递以下数组时,结果如下所示:
WriteLine(CheckSwitch(new[] { 1, 2, 10 })); // prints 1
WriteLine(CheckSwitch(new[] { 1, 2, 7, 3, 3, 10 })); // prints 1
WriteLine(CheckSwitch(new[] { 1, 2 })); // prints 2
WriteLine(CheckSwitch(new[] { 1, 3 })); // prints 3
WriteLine(CheckSwitch(new[] { 1, 3, 5 })); // prints 4
WriteLine(CheckSwitch(new[] { 2, 5, 6, 7 })); // prints 50
您还可以捕获切片模式的结果:
public static string CaptureSlice(int[] values)
=> values switch
{
[1, .. var middle, _] => $"Middle {String.Join(", ", middle)}",
[.. var all] => $"All {String.Join(", ", all)}"
};
列表模式适用于任何可数和可索引的类型——这意味着它具有可访问的 Length 或 Count 属性,并且具有 int 或 System.Index 参数的索引器。切片模式适用于任何可数和可切片的类型——这意味着它具有一个可访问的索引器,该索引器将 Range 作为参数,或者具有一个具有两个 int 参数的可访问的 Slice 方法。
我们正在考虑在 IEnumerable 类型上添加对列表模式的支持。如果您有机会使用此功能,请告诉我们您对此的想法。
C# 11 预览:参数空值检查
在提案参数空检查中阅读有关此更改的更多信息。
我们将此功能放入此早期预览版中,以确保我们有时间获得反馈。已经讨论过一种非常简洁的语法与一种更冗长的语法。我们希望获得客户反馈以及有机会尝试此功能的用户。
使用样板代码的变体来验证方法参数是否为空是很常见的,例如:
public static void M(string s)
{
if (s is null)
{
throw new ArgumentNullException(nameof(s));
}
// Body of the method
}
使用参数空检查,您可以通过添加 !! 到参数名称来缩写您的意图:
public static void M(string s!!)
{
// Body of the method
}
将生成代码以执行空值检查。生成的空值检查将在方法中的任何代码之前执行。对于构造函数,空值检查发生在字段初始化、调用基构造函数和调用 this 构造函数之前。
此功能独立于可空引用类型 (NRT),尽管它们可以很好地协同工作。 NRT 可帮助您在设计时了解 null 是否可能。参数空值检查可以更轻松地在运行时检查空值是否已传递给您的代码。当您的代码与可能未启用 NRT 的外部代码交互时,这一点尤其重要。
检查和 if (param is null) throw new ArgumentNullException(...) 是等效的。当多个参数包含 !! 运算符,则检查将按照声明参数的顺序进行。
下面是一些 !! 在哪里可以使用的限制规则:
- 只有在有实现时才能将空检查应用于参数。例如,抽象方法参数不能使用 !!。其他不能使用的情况包括:
- 外部方法参数。
- 委托参数。
- 当方法不是默认接口方法 (DIM) 时的接口方法参数。
- 空值检查只能应用于可以检查的参数。
根据第二条规则排除的场景示例是丢弃和输出参数。可以对 ref 和 in 参数进行空值检查。
允许对索引器参数进行空检查,并将检查添加到 get 和 set 访问器。例如:
public string this[string key!!] { get { ... } set { ... } }
Null-checks 可以用于 lambda 参数,无论它们是否被括号括起来:
// An identity lambda which throws on a null input
Func<string, string> s = x!! => x;
异步方法可以有空检查参数。调用方法时会发生空值检查。
该语法对迭代器方法的参数也有效。调用迭代器方法时会发生空值检查,而不是遍历底层枚举器时。这适用于传统或异步迭代器:
class Iterators {
IEnumerable<char> GetCharacters(string s!!) {
foreach (var c in s) {
yield return c;
}
}
void Use() {
// The invocation of GetCharacters will throw
IEnumerable<char> e = GetCharacters(null);
}
}
与可空引用类型的交互
任何具有 !! 的参数应用于其名称的运算符将以可空状态为非空开始。即使参数本身的类型可能为 null,也是如此。这可能发生在显式可为空的类型(例如字符串?)或不受约束的类型参数中。
当 !!参数上的语法与参数上的显式可空类型相结合,编译器将发出警告:
void WarnCase<T>(
string? name!!, // CS8995 Nullable type 'string?' is null-checked and will throw if null.
T value1!! // Okay
)
构造函数
当您从代码中的显式空检查更改为使用空验证语法 (!!) 进行空检查时,会有一个很小但可以观察到的变化。您的显式验证发生在使用 this 调用的字段初始值设定项、基类构造函数和构造函数之后。使用参数空检查语法执行的空检查将在任何这些执行之前发生。早期的测试人员发现这个顺序很有帮助,我们认为这种差异很少会对代码产生不利影响。但在从显式空检查转移到新语法之前,请检查它是否不会影响您的程序。
设计注意事项
您可以听到 Jared Parsons 在 2022 年 2 月 9 日的 .NET 语言和运行时社区站会中的演讲。当 Jared 加入我们的行列时,该剪辑开始了大约 45 分钟,更多地讨论了将这个功能引入预览的决定,并做出了回应一些常见的反馈。
有些人在看到 PR 在 .NET 运行时使用此功能时了解了此功能。 Microsoft 的其他团队提供了有关 C# 的重要 dogfooding 反馈。得知 .NET 运行时使用这种新的空检查语法删除了近 20,000 行代码,这令人兴奋。
在参数名称上的语法是 !!。它在名称上,而不是类型上,因为这是在您的代码中如何处理该特定参数的一个特征。我们决定不使用属性是因为它会如何影响代码的可读性,并且因为属性很少会像此功能那样影响程序的执行方式。
我们考虑并拒绝了对所有可空参数进行空检查的全局设置。参数空值检查强制设计选择如何处理空值。有许多方法,其中 null 参数是有效值。在类型不为 null 的任何地方都这样做会过度,并且会对性能产生影响。仅限制于易受 null 影响的方法(例如公共接口)将是极其困难的。我们还从 .NET 运行时工作中了解到,有很多地方不适合进行检查,因此需要按参数选择退出机制。我们目前认为运行时空值检查的全局方法可能不合适,如果我们考虑使用全局方法,那将是一个不同的特性。
总结
Visual Studio 17.1 和 .NET SDK 6.0.200 提供了对 C# 11 的早期了解。您可以在插值字符串的花括号(孔)内使用参数空检查、列表模式和新行。
我们希望您通过更新 Visual Studio 或下载最新的 .NET SDK,然后将 LangVersion 设置为预览来查看 C# 11 预览功能。
我们期待听到您的想法,在这里或通过 GitHub 上的 CSharpLang 存储库中的讨论!
原文链接
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
欢迎转载、使用、重新发布,但务必保留文章署名 郑子铭 (包含链接: http://www.cnblogs.com/MingsonZheng/ ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。
如有任何疑问,请与我联系 (MingsonZheng@outlook.com) 。
【译】C# 11 特性的早期预览的更多相关文章
- PyCharm:2017.3版即将新增科学计算模式,预览版现在可以下载使用
编译:Lemon,原文作者:Ernst Haagsman 公众号:Python数据之道(ID:PyDataRoad) pycharm:2017.3版即将新增科学计算模式 在JetBrains将发布的新 ...
- 【译】Visual Studio 15 预览版更新说明
序:恰逢Build2016大会召开,微软发布了VS2015的update2更新包和VS2016预览版.本人正在提升英文水平中,于是在这里对VS2016预览版的官方文档进行了部分翻译.因为VS有些功能使 ...
- 5个难以置信的VS 2015预览版新特性
Visual Studio 2015 Preview包含了很多强大的新特性,无论你是从事WEB应用程序开发,还是桌面应用程序开发,甚至是移动应用开发,VS 2015都将大大提高你的开发效率.有几个特性 ...
- .NET 4.5.1 预览版新特性
上个月的微软Build大会上宣布了.NET 4.5.1的推出,Heydarian的这个演讲题为".NET开发中的新内容",涵盖了.NET Framework中一些重要的新特性. H ...
- Windows Phone 8.1SDK新特性预览
前言 Windows Phone 8.1的预览版将在近期推送,WP 8.1的SDK也已经进入到RC阶段,可以从这里安装.本次更新的SDK被直接集成到了VS2013Update2里面,不再是单独的 ...
- Asp.net Core中SignalR Core预览版的一些新特性前瞻,附源码(消息订阅与发送二进制数据)
目录 SignalR系列目录(注意,是ASP.NET的目录.不是Core的) 前言 一晃一个月又过去了,上个月有个比较大的项目要验收上线.所以忙的脚不沾地.现在终于可以忙里偷闲,写一篇关于Signal ...
- avalon1.3的新特性预览
avalon1.2的性能优化风暴很快就告一段落,入职也快一个月了,许多乱七八糟的事也少了下来,估计未来一个月会有许多好东呈现给大家. 首先是一个性能检测工具.由于MVVM是将原本由人脑干的事,转到各种 ...
- C# 9.0 新特性预览 - 类型推导的 new
C# 9.0 新特性预览 - 类型推导的 new 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大 ...
- C# 9.0 新特性预览 - 空参数校验
C# 9.0 新特性预览 - 空参数校验 前言 随着 .NET 5 发布日期的日益临近,其对应的 C# 新版本已确定为 C# 9.0,其中新增加的特性(或语法糖)也已基本锁定,本系列文章将向大家展示它 ...
随机推荐
- Servlet-整个Servlet类的继承体系
- 《手把手教你》系列技巧篇(六十一)-java+ selenium自动化测试 - 截图三剑客 -下篇(详细教程)
1.简介 按照计划宏哥今天将介绍java+ selenium自动化测试截图操作实现的第三种截图方法,也就是截图的第三剑客 - 截取某个元素(或者目标区域)的图片.在测试的过程中,有时候不需要截取整个屏 ...
- 项目管理软件jira安装
JIRA是Atlassian公司出品的项目与事务跟踪工具,被广泛应用于缺陷跟踪.客户服务.需求收集.流程审批.任务跟踪.项目跟踪和敏捷管理等工作领域. 官方文档https://confluence.a ...
- Java虚拟机的意义
什么是Java虚拟机? 作为程序员,大家都知道写的代码都是在Java虚拟机上运行的,但大家是否知道,Java虚拟机又是什么呢? 先看看网上搜到有关JAVA虚拟机的介绍 : 虚拟机是一种抽象化的计算机, ...
- springboot实战小项目-简要介绍、vue项目创建
因为菜,所以要好好学习! 一.项目介绍:这是一个后台管理系统,准备实现的功能: 1.登录.注册.个人信息查看.退出登录 2.根据关键字查询用户.新增用户.根据id或者其他字段排序.编辑用户信息.删除用 ...
- 「JOISC 2016 Day 1」棋盘游戏
「JOISC 2016 Day 1」棋盘游戏 先判无解:第1,3行有连续的空格或四个角有空格. 然后可以发现有解的情况第1,3行可以在任意时间摆放. 对于某一列,若第2行放有棋子,那么显然可以把棋盘分 ...
- AT2402 [ARC072D] Dam
首先我们可以将 \(t_i \times v_i\) 看作一个整体,不妨令 \(x_i = v_i, y_i = t_i \times v_i\) 这样两堆水混合后相当于将两个维度相加,方便了计算. ...
- NSArray 遍历
1.NSArray的下标遍历 NSArray *arr = @[p1, p2, p3, p4, p5]; for (int i = 0; i < arr.count; ++i) { Person ...
- 简单仿京东"筛选"界面 双导航栏控制器共存 by Nicky.Tsui
大概就是这么一个效果 如图.大概可以看到,"筛选"视图后面有一层视图盖住了后面原来的视图 那么我们可以通过加一个view到导航栏控制器的view里面来实现 //该view作为全局变 ...
- mybatis的一对多(collection)
使用图解: 低效率查询: 高效率查询: 1 查询用联合查询 2<collection 里面不写column