准备工作:

Visual Studio 2019 Preview版本中并没有包含所有的C# 8.0的新功能,但目前也有一些可以试用了。在开始之前,需要进行入两项设置:

  1. 将Framework设置为.net core 3.0
  2. 将C#语法设置为8.0

也可以直接编辑.csproj文件,修改TargetFramework和LangVersion为如下形式:

<TargetFramework>netcoreapp3.0</TargetFramework>
     <LangVersion>8.0</LangVersion>

Nullable reference types

空引用对于所有编程者来说相信都是一个非常头痛的问题,图灵奖得主Tony Hoare 就把包含空引用的编程语言用定义为一个十亿美元的错误Null References: The Billion Dollar Mistake

首先还是来一段简单的代码:

string s = null;
     Console.WriteLine($"The first letter of {s} is {s[0]}");

这段代码编译没有问题,但运行的时候会抛空引用异常的。

在C# 8.0中,开启了空引用异常检测后,上述代码在编译器就会检查出告警来。

并且它会结合上下文判断,如果该值不会为null,则不会告警,非常智能。

细心的朋友可能会发现,虽然在下面使用的地方没有告警,但是变量初始化的地方还是报告警了。如果我们的程序本身就是允许null值改怎么办呢,放任告警不管也是不合适的做法。

针对这个问题,C#引入了一个新的声明为可空对象的语法:

string? s = null;

也就是在类型后加一个?符号,表面该对象是一个可空对象。

由于这个行为和之前的C#版本是不一致的,因此默认是没有开启这个功能的,我们需要在csproj文件中打开这个设置:

<LangVersion>8.0</LangVersion>
     <NullableReferenceTypes>true</NullableReferenceTypes>

不知道在后续的VS的版本中会不会直接再界面上添加这一设置。

最后总结一下,Nullable reference types主要干了两件事:

  1. 可以通过对象声明判断该对象是否可能为空。
  2. 当可空对象使用在不可空的场景是,会报告警。

虽然之前有一些第三方插件也集成了类似的功能,如Resharper的Null Check,但把这个功能集成到了编译器上后更加简洁好用。

C#的空对象检查在设计期间也有好几种语法方案,目前这种方案既解决了问题,又对现有代码保持完全兼容,还能对现有代码潜在性问题能进行分析,是一种比较理想的方案的。如果以后能通过设置,将空引用的告警级别可以设置为错误就更好了。

Ranges and indices

范围和索引是C#新引入的语法,它主要引入了两个对象Range和Index。

Index

首先还是来看一个简单的例子。

var numbers = new[] { 1, 2, 3, 4, 5, 6, 7 };
     Index i1 = 3; // number 3 from beginning
     Index i2 = ^2; // number 2 from end
     Console.WriteLine($"{numbers[i1]}, {numbers[i2]}"); // "4, 6"

这个例子简单的演示了一下Index的用法,Index本身还是类似于之前的int索引的,它也可以和int类型转换。但Index在int索引的方式扩展了一下,支持从后往前访问,也就是我们说的倒数位。

Index i2 = ^2; // number 2 from end

Range

基于Index组成起点和终点,可以组成了一个范围Range,根据Range可以对数组进行切片。

     Range range = Range.Create(i1, i2);
     int[] slice = numbers[range];        //"4, 5"

".."运算符

为了快速表示一个Range,C#还映入了一个新的运算符".."如上面的代码就可以简写为:

     int[] slice = numbers[i1..i2];        //"4, 5"

".."语法不复杂,通过".."连接的开头和结尾的索引,用来表示一个范围。为了使用方便,".."运算符的开头和结尾是可以省略的,常用的大致就有这几种形式。

     string text = "hello c# 8.0";
     Console.WriteLine(text[..]); //"hello c# 8.0"
     Console.WriteLine(text[^3..]);      //"8.0"
     Console.WriteLine(text[..5]);       //"hello"
     Console.WriteLine(text[6..]);       //"c# 8.0"

通过".."运算符,我们描述切片时可以清晰很多,例如如下这个常见的求字符串子串的例子:

     var sub = text.Substring(text.Length - 6, 6);
     var sub2 = text[^6..];

.net 3.0的很多类都内置了对Range的切片操作,常见的有:

  1. 字符串用来子串
  2. Array用来划获取子数组
  3. span<T>用来切片

Asynchronous streams

异步流能一种拉的方式进行异步迭代,配合async编程可以以异步的方式把socket流像本地文件一样解析,相信这是很多用c#写socket程序的程序员所喜欢的一个特性。

一个简单的示例如下:

     static async IAsyncEnumerable<string> GetNamesAsync()
     {
        await Task.Delay(1000);
        yield return "hello";
        await Task.Delay(1000);
        yield return "world";
     }
    
     await foreach (var name in GetNamesAsync())
     {
        Console.WriteLine(name);
     }

我在Visual Studio 2019 preview中试用这个功能的时候,发现无法编译通过。MS解释说这个是VS和.net core代码没有完全匹配上所致,我们可以手动添加相关代码以完成这一编译过程。

namespace System.Threading.Tasks
{
using System.Runtime.CompilerServices;
using global::System.Threading.Tasks.Sources; internal struct ManualResetValueTaskSourceLogic<TResult>
{
private ManualResetValueTaskSourceCore<TResult> _core;
public ManualResetValueTaskSourceLogic(IStrongBox<ManualResetValueTaskSourceLogic<TResult>> parent) : this() { }
public short Version => _core.Version;
public TResult GetResult(short token) => _core.GetResult(token);
public ValueTaskSourceStatus GetStatus(short token) => _core.GetStatus(token);
public void OnCompleted(Action<object> continuation, object state, short token, ValueTaskSourceOnCompletedFlags flags) => _core.OnCompleted(continuation, state, token, flags);
public void Reset() => _core.Reset();
public void SetResult(TResult result) => _core.SetResult(result);
public void SetException(Exception error) => _core.SetException(error);
}
} namespace System.Runtime.CompilerServices
{
internal interface IStrongBox<T> { ref T Value { get; } }
}

其他语法

本身C# 8.0是还有几个其它语法的,如接口默认方法,高级模式匹配等。这些语法在目前的VS 2019 preview中还无法体验。估计后续会慢慢放开的,到时候我再写相关文章介绍它们。

相关文章:

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

Visual Studio 2019 preview中体验C# 8.0新语法的更多相关文章

  1. 2019年第一天——使用Visual Studio 2019 Preview创建第一个ASP.Net Core3.0的App

    一.前言: 全文翻译自:https://www.talkingdotnet.com/creating-first-asp-net-core-3-0-app-visual-studio-2019/ Vi ...

  2. Visual studio 2019 preview & C# 8 initial experience

    Visual studio 2019 preview & C# 8 initial experience       using System; using static System.Con ...

  3. Visual Studio 2015速递(1)——C#6.0新特性怎么用

    系列文章 Visual Studio 2015速递(1)——C#6.0新特性怎么用 Visual Studio 2015速递(2)——提升效率和质量(VS2015核心竞争力) Visual Studi ...

  4. 在Visual Studio 2015 Preview 中使用Github 版本控制

    打开Visual Studio,新建项目,右下角勾选,如下图: 点击‘OK’后,出现下图窗口,选择'Git' : 如果是现有项目可以在‘文件’菜单下找到‘Add to Source Control’ ...

  5. [翻译] 使用 Visual Studio 2019 来提高每个开发人员的工作效率

    [翻译] 使用 Visual Studio 2019 来提高每个开发人员的工作效率 原文: Making every developer more productive with Visual Stu ...

  6. Visual Studio 2013 Preview 新功能

    先来看一下Visual Studio的版本历史: 1. Visual Studio.NET 2002 2. Visual Studio.NET 2003 3. Visual Studio.NET 20 ...

  7. [翻译] Visual Studio 2019 RC版发布

    [翻译] Visual Studio 2019 RC版发布 原文: Visual Studio 2019 Release Candidate (RC) now available 今天,我们将分享 V ...

  8. Visual Studio 2019预览,净生产力

    本文章为机器翻译. https://blogs.msdn.microsoft.com/dotnet/2018/12/13/visual-studio-2019-net-productivity/ 该文 ...

  9. Making every developer more productive with Visual Studio 2019

    Today, in the Microsoft Connect(); 2018 keynote, Scott Guthrie announced the availability of Visual ...

随机推荐

  1. HTML5 移动开发(CSS3设计移动页面样式)

    1.如何创建CSS样式表 2.CSS3的卓越特性 3.基于设备属性改变样式的媒体查询 4.如何使用属性改变元标签创建更美观移动页面   层叠样式表是移动WEB开发中的一个重要组成部分,本次分享将学到如 ...

  2. 第5月第21天 bugly ios证书位置

    1.bugly 一. 本地测试 补丁编写规则参见: JSPatch 将补丁文件main.js拖拽到工程内: 开启 BuglyConfig 中的热更新本地调试模式: BuglyConfig *confi ...

  3. 用U盘安装 win7 ”找不到任何设备驱动程序“ 和 系统出现 windows boot manager 解决方案

    用U盘安装win7系统时,系统交替的出现了如下的2个错误,捣鼓了半天,记录下来: 问题1描述: 安装win7时  ”找不到任何设备驱动程序“  问题2描述: 安装win7时,用U盘启动后, 系统出现 ...

  4. Wireshark按照域名过滤

    HTTP协议 http.host == "http://baidu.net" DNS协议 dns.qry.name=="www.baidu.com"

  5. 【坐在马桶上看算法】算法4:队列——解密QQ号

            新学期开始了,小哈是小哼的新同桌(小哈是个小美女哦~),小哼向小哈询问QQ号,小哈当然不会直接告诉小哼啦,原因嘛你懂的.所以小哈给了小哼一串加密过的数字,同时小哈也告诉了小哼解密规则. ...

  6. 驱动程序vmci.sys版本不正确。请尝试重新安装 VMware

    今天在测试一台服务器,安装在虚拟机里面,但是发现在安装后,重启了一下电脑,出现了这个错误: 无法获取 vmci 驱动程序版本: 句柄无效.驱动程序 vmci.sys 版本不正确.请尝试重新安装 VMw ...

  7. darknet

    darknet第二作者:https://github.com//AlexeyAB/darknet#how-to-train-to-detect-your-custom-objects yolov3实现 ...

  8. Luogu P1549 棋盘问题(2)

    题意 在N×N的棋盘上(1≤N≤10),填入1,2,-,N^2,共N^2个数,使得任意两个相邻的数之和为素数. 思路 先线性筛(非标准版),然后用a数组记录以i为下标的数是不是质数(就是标记数组),然 ...

  9. Java登陆拦截器

    package com.beidou.warehouseerp.interceptor; import com.alibaba.fastjson.JSON; import com.beidou.war ...

  10. .NetCore利用Swagger生成 XML文档需要注意生成路径的地址

    发布的时候如果用 release dotnet publish --configuration release dotnet publish 默认都是debug 会出现 XML丢失问题,其实可以看下工 ...