C# 8.0 的新特性( NET Framework 4.8 与 Visual Studio 2019 )
C#8.0 于 2019年4月 随 .NET Framework 4.8 与 Visual Studio 2019 一同发布
使用VS2019体检C#8.0新功能:
编辑.csproj文件,添加如下代码
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
一、可空引用类型(Nullable reference types)
引用类型将会区分是否可空,可以从根源上解决 NullReferenceException。
#nullable enable
void M(string? s)
{
Console.WriteLine(s.Length); // 产生警告:可能为 null
if (s != null)
{
Console.WriteLine(s.Length); // Ok
}
}
#nullable disable
二、异步流(Async streams)
考虑到大部分 Api 以及函数实现都有了对应的 async版本,而 IEnumerable<T>和 IEnumerator<T>还不能方便的使用 async/await就显得很麻烦了。
但是,现在引入了异步流,这些问题得到了解决。
我们通过新的 IAsyncEnumerable<T>和 IAsyncEnumerator<T>来实现这一点。同时,由于之前 foreach是基于IEnumerable<T>和 IEnumerator<T>实现的,因此引入了新的语法await foreach来扩展 foreach的适用性。
async Task<int> GetBigResultAsync()
{
var result = await GetResultAsync();
if (result > ) return result;
else return -;
} async IAsyncEnumerable<int> GetBigResultsAsync()
{
await foreach (var result in GetResultsAsync())
{
if (result > ) yield return result;
}
}
三、范围和下标类型(Ranges and indices)
C# 8.0 引入了 Index 类型,可用作数组下标,并且使用 ^ 操作符表示倒数。
不过要注意的是,倒数是从 1 开始的。
Index i1 = ; // 下标为 3
Index i2 = ^; // 倒数第 4 个元素
int[] a = { , , , , , , , , , };
Console.WriteLine($"{a[i1]}, {a[i2]}"); // "3, 6"
除此之外,还引入了 “..” 操作符用来表示范围(注意是左闭右开区间)。
var slice = a[i1..i2]; // { 3, 4, 5 }
关于这个下标从 0 开始,倒数从 1 开始,范围左闭右开。
四、模式匹配表达式(Switch expressions )
典型的模式匹配语句,只不过没有用“match”关键字,而是沿用了了“switch”关键字
object figure = "";
var area = figure switch
{
Line _ => ,
Rectangle r => r.Width * r.Height,
Circle c => c.Radius * 2.0 * Math.PI,
_ => throw new UnknownFigureException(figure)
};
C# 8.0中的模式匹配相对C# 7.0来说有了进一步的增强,对于如下类:
class Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
首先来看C# 7.0中一个经典的模式匹配示例:
static string Display(object o)
{
switch (o)
{
case Point p when p.X == && p.Y == :
return "origin";
case Point p:
return $"({p.X}, {p.Y})";
default:
return "unknown";
}
}
在C# 8.0中,它有更加精简的写法。
1、Switch表达式
在C# 8.0中,可以利用新的switch方式成模式匹配:
static string Display(object o) => o switch
{
Point p when p.X == && p.Y == => "origin",
Point p => $"({p.X}, {p.Y})",
_ => "unknown"
};
它利用一条switch语句完成了模式匹配,第一样看上去要简洁一些。不过,它还有更多更简单的写法。
2、Property patterns
可以直接通过在属性上指定值作为判定条件,
static string Display(object o) => o switch
{
Point { X: , Y: } => "origin",
Point p => $"({p.X}, {p.Y})",
_ => "unknown"
};
也可以将属性值传递出来。
static string Display(object o) => o switch
{
Point { X: , Y: } => "origin",
Point { X: var x, Y: var y } => $"({x}, {y})",
_ => "unknown"
};
3、Positional patterns
利用解构函数,可以写出更加精简的表达式。
static string Display(object o) => o switch
{
Point(, ) => "origin",
Point(var x, var y) => $"({x}, {y})",
_ => "unknown"
};
如果没有类型转换,则可以写得更加简单了:
static string Display(Point o) => o switch
{
(, ) => "origin",
(var x, var y) => $"({x}, {y})"
};
4、非空判断
如果只是判断空和非空,则有最简单的模式:
{ } => o.ToString(),
null => "null"
5、Tuple patterns
也支持直接对ValueTuple进行模式匹配,用起来非常灵活。
static State ChangeState(State current, Transition transition, bool hasKey) =>
(current, transition, hasKey) switch
{
(Opened, Close, _) => Closed,
(Closed, Open, _) => Opened,
(Closed, Lock, true) => Locked,
(Locked, Unlock, true) => Closed,
_ => throw new InvalidOperationException($"Invalid transition")
};
五、递归模式语句(recursive patterns)
现在可以这么写了(patterns 里可以包含 patterns)
IEnumerable<string> GetEnrollees()
{
foreach (var p in People)
{
if (p is Student { Graduated: false, Name: string name }) yield return name;
}
}
C# 8.0 的新特性( NET Framework 4.8 与 Visual Studio 2019 )的更多相关文章
- C# 7.0 中的新特性((.NET Framework 4.7 与 Visual Studio 2017 ))
C#7.0 于 2017年3月 随 .NET 4.7 和 VS2017 发布. 一. out 变量(out variables) 以前我们使用out变量必须在使用前进行声明,C# 7.0 给我们提供了 ...
- C# 8.0 的新特性概览和讲解
本文转自 https://blog.csdn.net/hez2010/article/details/84036742 C# 8.0 的新特性概览和讲解 前言 新的改变 可空引用类型(Nullable ...
- php5.3到php7.0.x新特性介绍
<?php /*php5.3*/ echo '<hr>'; const MYTT = 'aaa'; #print_r(get_defined_constants()); /* 5.4 ...
- paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较
paip.php 5.0 5.3 5.4 5.5 -6.0的新特性总结与比较 PHP5的新特性 2 · 对象的参照过渡是默认的(default) 3 · 引入访问属性的限制 3 · 引入访问方法的限 ...
- NodeJS 框架 Express 从 3.0升级至4.0的新特性
NodeJS 框架 Express 从 3.0升级至4.0的新特性 [原文地址:√https://scotch.io/bar-talk/expressjs-4-0-new-features-and-u ...
- 相比于python2.6,python3.0的新特性。
这篇文章主要介绍了相比于python2.6,python3.0的新特性.更详细的介绍请参见python3.0的文档. Common Stumbling Blocks 本段简单的列出容易使人出错的变动. ...
- MySQL 8.0 InnoDB新特性
MySQL 8.0 InnoDB新特性 1.数据字典全部采用InnoDB引擎存储,支持DDL原子性.crash safe,metadata管理更完善 2.快速在线加新列(腾讯互娱DBA团队贡献) 3. ...
- Atitit jquery 1.4--v1.11 v1.12 v2.0 3.0 的新特性
Atitit jquery 1.4--v1.11 v1.12 v2.0 3.0 的新特性 1.1. Jquery1.12 jQuery 2.2 和 1.12 新版本发布 - OPEN资讯.h ...
- [PHP] 从PHP 5.6.x 移植到 PHP 7.0.x新特性
从PHP 5.6.x 移植到 PHP 7.0.x 新特性: 1.标量类型声明 字符串(string), 整数 (int), 浮点数 (float), 布尔值 (bool),callable,array ...
随机推荐
- spring security的BCryptPasswordEncoder加密和对密码验证的原理
目录 BCryptPasswordEncoder加密和对密码验证的原理 一.加密算法和hash算法的区别 二.源码解析 1. encode方法 2. BCrypt.hashpw方法 3. matche ...
- 【转】Fuel-Openstack的搭建(一)
原文链接:https://blog.csdn.net/qq_35180983/article/details/82181496 2.1安装前的准备操作: 首先,我们需要准备以下操作: 2.1.1 下载 ...
- C++中的虚函数以及虚函数表
一.虚函数的定义 被virtual关键字修饰的成员函数,目的是为了实现多态 ps: 关于多态[接口和实现分离,父类指针指向子类的实例,然后通过父类指针调用子类的成员函数,这样可以让父类指针拥有多种形态 ...
- Linux下的JMeter部署及使用
之前都是在windows环境使用JMeter,是有操作界面的.但是最近需要在Linux环境下使用,现将操作步骤记录下来 在安装JMeter之前,需要在Linux下安装JDK并配置环境变量,这里跳过 1 ...
- Linux08 文件系统
对于磁盘等各类存储设备中所有的数据都以0和1的概念,但对于用户来说,0和1是没有任何意义的,这时候就需要一种类似于“翻译”的机制存在于用户和磁盘之间,Linux中采用的是文件系统+虚拟文件系统(Vir ...
- 我在LeetCode的首次刷题
到现在为止,我才发现我的博客一篇感受,心得,体会之言都没有. 今天就来随便扯扯. 刷题,是我最近一直在干的事情.也就每天写一两个.忘了就没写这种.也收藏了好几个刷题网站,当然第一次接触肯定是 WUST ...
- PB连接ORALCE数据库方法
本地必须配置连接服务
- [洛谷P5377][THUPC2019]鸽鸽的分割
题目大意:有一个圆,圆上有$n$个点,将这几个点两两连接,问最多分成几部分 题解:发现这相当于一个平面图,由欧拉公式得($F$为平面分割块数,$E$为平面图边数,$V$为平面图点数):$$F=E-V+ ...
- 【洛谷 P3346】 [ZJOI2015]诸神眷顾的幻想乡(后缀自动机)
题目链接 广义sam+不同子串个数.. 找到所有入度为\(0\)的点开始\(dfs\),建出广义sam. 然后就是不同子串个数了 #include <cstdio> #include &l ...
- spark源码阅读--SparkContext启动过程
##SparkContext启动过程 基于spark 2.1.0 scala 2.11.8 spark源码的体系结构实在是很庞大,从使用spark-submit脚本提交任务,到向yarn申请容器,启 ...