[翻译]初试C# 8.0

原文地址: https://blogs.msdn.microsoft.com/dotnet/2018/12/05/take-c-8-0-for-a-spin/

初试C# 8.0

昨天我们宣布了Visual Studio 2019的第一个预览版(使用Visual Studio 2019提高每个开发人员的工作效率)和.NET Core 3.0(宣布.NET Core 3预览1和开源Windows桌面框架)。

其中一个令人兴奋的方面是你可以使用C#8.0中的一些功能!在这里,我将带您进行一次导游,了解您可以在预览中尝试的三种新的C#功能。并非所有C#8.0功能都可用。如果您想了解所有主要功能,请阅读最近发布Building C# 8.0,或查看Channel 9或YouTube。

做好准备

首先,下载并安装.NET Core 3.0的预览版1和Visual Studio的2019的预览版1。在Visual Studio中,确保选择工作负载“.NET Core跨平台开发”(如果您忘记了,可以稍后通过打开Visual Studio安装程序并单击Visual Studio 2019预览频道上的“修改”来添加它)。

启动Visual Studio 2019预览版,创建新项目,然后选择“Console App(.NET Core)”作为项目类型。

项目启动并运行后,将其目标框架更改为.NET Core 3.0(在解决方案资源管理器中右键单击该项目,选择“属性”并使用“应用程序”选项卡上的下拉菜单)。然后选择C#8.0作为语言版本(在项目页面的Build选项卡上单击“Advanced ...”并选择“C#8.0(beta)”)。

现在,您可以轻松获得所有语言功能和支持框架类型!

可空的引用类型

可空引用类型功能旨在警告您代码中的null不安全行为。既然我们之前没有这样做过,那么现在就开始改变吧!为避免这种情况,您需要选择加入该功能。

不过,在我们开启它之前,让我们写一些非常糟糕的代码:

640?wx_fmt=png

如果你运行它,你当然会得到一个空引用异常。你陷入了黑洞!你怎么知道不要在特定的地方间接引用s?嗯,因为在前一行分配了null。但是在现实生活中,它可能不是在前一行,而是在你编写代码的三年后在地球另一端运行的其他人程序集中。你怎么知道不写那个?这是可空引用类型要回答的问题!所以让我们打开它们吧!

对于一个新项目,你应该立即打开它们。事实上,我认为它们应该在新项目中默认启用,但我们在预览中没有这样做。打开它们的方法是将以下行添加到.csproj文件中,例如在切换到上面的C#8.0时刚刚插入的LanguageVersion之后:

<NullableReferenceTypes>true</NullableReferenceTypes>

保存.csproj文件并返回到您的程序:发生了什么?你有两个警告!每个代表一个功能的“一半”。让我们依次看看它们。第一个是null这一行:

string s = null;

它抱怨你将null赋给“不可空类型”:啥?!?当打开该功能时,在普通的引用类型中不再欢迎使用null,例如string!因为,你知道吗,null不是一个字符串!我们一直假装在过去的五十年在面向对象编程,但实际上null并不是一个对象:这就是为什么每当你试图将它做为对象时一切都会爆炸!

所以不多说:null是禁止的,除非你要求它。你是怎么要求的?通过使用可空的引用类型,例如string?。尾随问号表示允许null:

string? s = null;

警告消失了:我们已明确表达了此变量保持null的意图,所以现在没问题了。

直到下一行代码!在该行:

WriteLine($"The first letter of {s} is {s[0]}");

它抱怨s中s[0],你可能会间接引用一空引用。果然:是!干得好,编译器!你怎么解决它?嗯,这几乎取决于你 - 无论何种方式你得修复它!让我们尝试初学者的方法, 只在s非null时执行该行:

if (s != null) WriteLine($"The first letter of {s} is {s[0]}");

警告消失了!为什么?因为编译器可以看到,只有s不是null时才会走后面的代码。它实际上进行了全流分析,跟踪每行代码中的每个变量,以便密切关注它可能是null的和可能不是的位置。它会监视您的测试和作业,并进行簿记(bookkeeping)。

我们试试另一种方法:

WriteLine($"The first letter of {s} is {s?[0] ?? '?'}");

这使用null条件索引运算符s?[0],它避免了间接引用,如果s为null ,则生成null。现在我们有一个可空的char?,但是null合并运算符?? '?'替换null值为字符 '?'。因此避免了所有null间接引用。编译器很高兴,没有给出警告。

正如您所看到的,该功能可以让您在编写代码时保持诚实:它会强制您在系统中使用null时通过使用可空的引用类型来表达您的意图。并且一旦出现null,它就会强制您负责任地处理它,让您在存在可能间接引用null值以触发空引用异常的风险时进行检查。

你现在完全null安全了吗?没有。有几种方法可以使null值漏掉并导致空引用异常:

  • 如果你调用没有可空的引用类型功能的代码(也许它是在该功能存在之前编译的),那么我们无法知道该代码的意图是什么:它没有区分可空和不可空 - 我们说它是“无视的”。所以我们给它一个通行证; 我们根本不会对此类调用发出警告。

  • 分析器本身有一些漏洞。其中大多数是安全和便利之间的权衡; 如果我们抱怨,那将很难修复。例如,当你编写时new string[10],我们创建一个充满null值的数组,类型为非null字符串。我们不会对此发出警告,因为编译器如何跟踪您初始化所有数组元素?

但总的来说,如果你广泛使用这个功能(即在任何地方打开它),它应该照顾绝大多数的空引用。

毫无疑问地,我们打算在现有代码上开始使用该功能!一旦打开它,您可能会收到很多警告。其中一些实际上代表了问题:是的,你发现了一个错误!其中一些可能有点烦人; 你的代码显然是null安全的,你只是没有工具来表达你的意图:你没有可空的引用类型!例如,在我们开始的行:

string s = null;

这在现有代码中将非常普遍!正如你所看到的那样,我们也确实在下一行发出了警告,我们试图间接引用它。因此,从安全的角度来看,此处的赋值警告严格来说是多余的:它使您在新代码中保持诚实,但修复现有代码中的所有事件并不会使其更安全。对于这种情况,我们正在处理一种模式,其中某些警告被关闭,当它不影响空安全性时,因此升级现有代码不那么令人生畏。

另一个有助于升级的功能是,您可以使用编译器指令#nullable enable#nullable disable在代码中“本地”打开或关闭该功能。这样你就可以逐步完成你的项目并逐步处理注释和警告。

要了解更多关于可空引用类型检查出Overview of Nullable types和Introduction to nullable tutorial。

为了更深入的设计理由,去年我在C#中写了一篇帖子Introducing Nullable Reference Types in C#。

如果您想让自己沉浸在设计工作的日常工作中,请查看GitHub上的Language Design Notes,或者Nullable Reference Types Specification。

范围和索引

使用索引数据结构时,C#的表现力越来越强。曾经想要简单的语法来切出数组,字符串或span的一部分吗?现在你可以!

继续将您的程序更改为以下内容:

640?wx_fmt=png

让我们来看看迭代名字数组的那段代码。修改foreach如下:

foreach (var name in names[1..4])

看起来我们正在迭代名字1到4。事实上代码运行时也确实如此!终点是排外的,即不包括元素4。1..4实际上是一个范围表达式,它不必像该处一样,作为索引操作的一部分出现。它有一种自己的类型,叫做Range。如果我们想要的话,我们可以把它拉到自己的变量中,它会起到同样的作用:

Range range = 1..4; 
foreach (var name in names[range])

范围表达式的终点不必是整数。事实上,它们属于一种类型,叫Index,可由非负数转换得来。但是你也可以使用一个新的^运算符创建Index,意思是“从末尾”。所以^1是从末尾开始1个:

foreach (var name in names[1..^1])

这会在数组的每一端去除一个元素,产生一个带有中间三个元素的数组。

范围表达式可以在任一端或两端打开。..^10..^1相同。1..1..^0相同。并且..0..^0相同:从头到尾。试试吧!尝试在Range的两端混合使用“从开始”和“从末尾”的Index,看看会发生什么。

范围不仅仅适用于索引器。例如,我们计划有重载string.SubStringSPan<T>.Slice以及使用Range参数的AsSpan扩展方法。这些不在.NET Core 3.0预览中。

异步流

IEnumerable<T>在C#中扮演着特殊的角色。“IEnumerables”代表各种不同的数据序列,并且语言具有用于消费和生成它们的特殊构造。

正如我们在当前的程序中看到的那样,它们通过foreach声明来消费,该声明涉及获取枚举器的苦差事,反复推进它,沿途提取元素,最后处理枚举器。并且可以使用迭代器生成它们:yield return按消费者要求产生元素。但两者都是同步的:当结果被请求时最好已经准备就绪,否则就会阻塞线程!

async和await加入到C#中用来处理当结果被请求时不一定准备好的情况。它们可以异步await,并且线程可以在其可用之前执行其他操作。但这仅适用于单个值,而不适用于随时间逐渐和异步生成的序列,例如来自IoT传感器的测量值或来自服务的流数据。

异步流在C#中将异步和枚举结合在一起!让我们看看,通过逐步“异步”我们当前的程序。

首先,让我们在文件的顶部添加另一个using指令:

using System.Threading.Tasks;

现在让我们通过在yield return名字之前增加一个异步延迟来模拟GetNames做了一些异步工作:

await Task.Delay(1000);yield return name;

当然,我们得到了一个错误: 只能在async方法中使用await。所以我们让它异步:

static async IEnumerable<string> GetNames()

现在我们被告知我们没有为异步方法返回正确的类型,这是公平的。但除了通常的Task东西之外,这次我们的类型列表中有了一个新的候选可以返回:IAsyncEnumerable

static async IAsyncEnumerable<string> GetNames()

就像我们已经生成了一个异步字符串流!根据命名指南,让我们重命名GetNames为GetNamesAsync。

static async IAsyncEnumerable<string> GetNamesAsync()

现在我们在Main方法中的这一行得到一个错误:

foreach (var name in GetNamesAsync())

不知道如何foreach一个IAsyncEnumerable<T>。这是因为异步流的foreach需要显式使用await关键字:

await foreach (var name in GetNamesAsync())

这是foreach的异步版本:采用异步流并等待每个元素!当然它只能在异步方法中这样做,所以我们必须使我们的Main方法异步。幸运的是,C#7.2增加了对它的支持:

static async Task Main(string[] args)

现在所有的混乱都消失了,程序是正确的。但是如果你尝试编译并运行它,你会得到一些令人尴尬的错误。那是因为我们搞砸了一下,并没有完全对齐.NET Core 3.0和Visual Studio 2019的预览。具体来说,有一种实现类型,异步迭代器利用它与编译器期望的不同。

您可以通过向项目添加单独的源文件来修复此问题,其中包含此桥接代码。再次编译,一切都应该工作得很好。

下一步

请让我们知道你的想法!如果您尝试这些功能并了解如何改进它们,请使用Visual Studio 2019预览中的反馈按钮。预览的整个目的是根据现实用户手中的功能如何进行最后一次校正,所以请告诉我们!

原文地址:https://www.cnblogs.com/waku/p/10094691.html


.NET社区新闻,深度好文,欢迎访问公众号文章汇总 http://www.csharpkit.com

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318526.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上帝造题的七分钟(ybtoj-树状数组)

文章目录题目描述解析代码thanks for reading&#xff01;题目描述 解析 差点活活恶心死 搬砖题 &#xff08;其实细节没有那么多&#xff0c;还是代码能力太差&#xff09; 利用矩阵的二维差分 加上树状数组搞一搞 就完事了&#xff08;我实在不想再写了 &#xff09; 洛谷…

.NET Core微服务之路:让我们对上一个Demo通讯进行修改,完成RPC通讯

最近一段时间有些事情耽搁了更新&#xff0c;抱歉各位了。上一篇我们简单的介绍了DotNetty通信框架&#xff0c;并简单的介绍了基于DotNetty实现了回路&#xff08;Echo&#xff09;通信过程。我们来回忆一下上一个项目的整个流程&#xff1a;当服务端启动后&#xff0c;绑定并…

Visual Studio 2019 首个预览版本抢先看,有啥新功能?

微软在 Connect 2018 大会上发布Visual Studio 2019 第 1 个预览版本。该预览版本中展示了许多变更&#xff0c;从 IDE 的启动行为&#xff0c;到代码重构功能&#xff1b;从搜索功能的更多用法&#xff0c;到更好的大型项目导航。这个预览版本展现了微软希望尽全力帮助开发人员…

模板:网络流(Dinic算法)

文章目录1.网络最大流题目描述解析反悔边分层&#xff08;避免环流&#xff09;时间优化代码2.费用流描述解析代码1.网络最大流 洛谷P3376 题目描述 给出一个网络图&#xff0c;以及其源点和汇点&#xff0c;求出其网络最大流。 解析 网络流的思想就是在原有的基础上不断进…

NC51272 棋盘覆盖

题目&#xff1a; 给出一张nn(n≤100) 的国际象棋棋盘&#xff0c;其中被删除了一些点&#xff0c;问可以使用多少1*2的多米 诺骨牌进行掩盖。 题解&#xff1a; 先进行黑白染色&#xff0c;相邻的两个黑白就是一个骨牌&#xff0c;又因为一个格子不能放多个骨牌&#xff0c;…

微软推出 VS Code 新特性,为 TypeScript 和 JavaScript 用户提供 AI 辅助开发功能

除了开发人员非常喜欢的IntelliSense和代码完成之外&#xff0c;今年早些时候&#xff0c;微软还发布了IntelliCode&#xff0c;提供了一组 AI 辅助开发功能。VS Code 团队现在宣布了一项新的实验性扩展&#xff0c;将 IntelliCode 带给了 TypeScript 和 JavaScript 用户。VS C…

NC107617 poj3020 Antenna Placement

问题&#xff1a; n * m的矩阵&#xff0c;有一些障碍点&#xff0c;用12的骨牌覆盖所有非障碍点 (12骨牌可重叠&#xff0c;骨牌可越界&#xff0c;骨牌可延伸到障碍点) 问最少需要 多少个。 题解&#xff1a; • 尽量用一个骨牌覆盖两个格子&#xff0c;覆盖不了了再重叠使…

货车运输(洛谷P1967)(倍增)

传送门 文章目录题目描述题目解析代码题目描述 题目解析 本题如果告诉你&#xff0c;城市形成了一棵树&#xff0c;是不是就迎刃而解了呢? 本题的关键就是把稠密图转化为一片森林&#xff08;就是可能有很多棵树啦&#xff09; 怎么转化呢? 考虑哪些边是没用的 如果AB已经可…

.NET Core实战项目之CMS 第十一章 开发篇-数据库生成及实体代码生成器开发

上篇给大家从零开始搭建了一个我们的ASP.NET Core CMS系统的开发框架&#xff0c;具体为什么那样设计我也已经在第十篇文章中进行了说明。不过文章发布后很多人都说了这样的分层不是很合理&#xff0c;什么数据库实体应该跟仓储放在一起形成领域对象&#xff0c;什么ViewModel应…

第1节 连通性强连通、割点和桥(一)

文章目录无向图割点、桥、双连通分量Tarjan算法求割点和桥&#xff08;割边&#xff09;代码&#xff1a;边双连通分量 和 点双连通分量代码边双连通分量 和 点双连通分量 的缩点有向图的弱连通与强连通强连通分量Kosaraju算法Tarjan算法代码&#xff1a;无向图割点、桥、双连通…

连通性(相关练习)

文章目录NC20603 [ZJOI2007]最大半连通子图题目&#xff1a;题解&#xff1a;代码&#xff1a;NC50403 嗅探器题目&#xff1a;题解&#xff1a;代码&#xff1a;NC51269 Network of Schools题目&#xff1a;题解&#xff1a;代码&#xff1a;NC106972 Cow Ski Area题目&#x…

ASP.NET Core WebAPI中使用JWT Bearer认证和授权

为什么是 JWT BearerASP.NET Core 在 Microsoft.AspNetCore.Authentication 下实现了一系列认证, 包含 Cookie, JwtBearer, OAuth, OpenIdConnect 等,Cookie 认证是一种比较常用本地认证方式, 它由浏览器自动保存并在发送请求时自动附加到请求头中, 更适用于 MVC 等纯网页系统的…

网络流专题(最大流与费用流)(一)

流量网络 • 想要将一些水从S运到T&#xff0c;必须经过一些水站&#xff0c;链接水站的是管道&#xff0c;每条管道都有它的最大能容纳的水量&#xff0c;求最多S到T能流多少流量。 基本概念 • 这是一个典型的网络流模型。我们先了解网络流的有关定义和概念。 • 若有向图G(…

eShopOnContainers 看微服务 ①:总体概览

一、简介eShopOnContainers是一个简化版的基于.NET Core和Docker等技术开发的面向微服务架构的参考应用。该参考应用是一个简化版的在线商城/电子商务微服务参考示例应用。其包含基于浏览器的Web应用、基于Xamarin的Android、IOS、Windows/UWP 移动应用&#xff0c;以及服务端应…

网络流专题(最大流与费用流)例题总结

文章目录NC 106056 poj1459 Power Network题目大意&#xff1a;题解&#xff1a;NC213817 [网络流24题]最小路径覆盖问题题目&#xff1a;题解&#xff1a;例2&#xff1a;NC213818 [网络流24题]魔术球问题题目&#xff1a;题解&#xff1a;方法2&#xff1a;NC 213820 [网络流…

周期长度和(KMP)

文章目录题目描述解析问题总结代码题目描述 解析 我们可以看到 如果A是B的周期 那么B一定可以写成&#xff1a; A1A2A1 的形式 注意到&#xff1a;A1就是KMP中的公共前后缀 要使A最大&#xff0c;要使A1最短 也就是求最短公共前后缀 这怎么求呢&#xff1f; 我们注意到&#x…

计算几何基础-1

文章目录基本概念点与向量的运算精度问题线段&#xff0c;射线和直线点积&#xff1a;夹角叉积向量的极角旋转一个向量求三角形面积直线交点点到直线距离点在直线上的投影判断两条线段是否相交点与直线的位置关系点是否在直线左侧点是否在直线上点是否在线段上点与多边形的位置…

.net core i上 K8S(四).netcore程序的pod管理,重启策略与健康检查

目录1.pod管理2.重启策略3.健康检查4.进入容器正文上一章我们已经通过yaml文件将.netcore程序跑起来了&#xff0c;但还有一下细节问题可以分享给大家。1.pod管理1.1创建podkubectl create -f netcore-pod.yaml我们创建一个netcore-pod.yaml文件&#xff0c;内容如下&#xff1…

洛谷P2680:运输计划(倍增、二分、树上差分)

传送门 文章目录题目描述解析问题代码题目描述 解析 求最大值的最小值 容易想到二分 然后。。。就没有然后了。。。 看了题解 学会了一个新技能&#xff1a;树上差分 &#xff08;其实学长之前好像讲过。。。&#xff09; 一般的&#xff0c;对于一条A到B的路径&#xff0c;如…

计算几何基础-2

文章目录直线&#xff1a;图形&#xff1a;求垂足求两圆交点直线与圆交点多边形问题判断一个点是否在任意多边形内部Pick定理凸包求点集的凸包水平法&#xff1a;增量法&#xff1a;半平面半平面交求半平面交直线&#xff1a; struct Line{point p,v;Line(){}Line(point _p.po…