加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

C# 8.0 的新特性

发布时间:2020-12-16 01:20:26 所属栏目:百科 来源:网络整理
导读:目录 可空引用类型(Nullable reference types) 异步流(Async streams) 范围和下标类型(Ranges and indices) 模式匹配表达式(Switch expressions ) Switch表达式 Property patterns Positional patterns 非空判断 Tuple patterns 递归模式语句(recur

?



使用VS2019体检C#8.0新功能:

编辑.csproj文件,添加如下代码

<PropertyGroup>
  LangVersion>preview</>
 >
回到顶部

可空引用类型(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 > 20) return result; else return -1; } async IAsyncEnumerable< GetBigResultsAsync() { await foreach (var result in GetResultsAsync()) { yield result; } }

回到顶部

范围和下标类型(Ranges and indices)

C# 8.0 引入了 Index 类型,可用作数组下标,并且使用 ^ 操作符表示倒数。
? 不过要注意的是,倒数是从 1 开始的。

Index i1 = 3;   下标为 3
Index i2 = ^4;  倒数第 4 个元素
int[] a = { 0,1,128);">2,128);">3,128);">4,128);">5,128);">6,128);">7,128);">8,128);">9 };
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 _ => 0,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; } int Y { public Point(int x,int y) => (X,Y) = (x,y); void Deconstruct(out int y) => (x,y) = (X,Y); }

首先来看C# 7.0中一个经典的模式匹配示例:

static string Display(object o) { (o) { case Point p when p.X == 0 && p.Y == : return origin"; case Point p: return $({p.X},{p.Y})defaultunknown; } }

在C# 8.0中,它有更加精简的写法。

Switch表达式

在C# 8.0中,可以利用新的switch方式成模式匹配:

object o) => o { Point p when p.X == 0 => => };

它利用一条switch语句完成了模式匹配,第一样看上去要简洁一些。不过,它还有更多更简单的写法。

Property patterns

可以直接通过在属性上指定值作为判定条件,

{ Point { X: 0 } => => };

也可以将属性值传递出来。

0 } => var x,Y: var y } => $({x},{y}) };

Positional patterns

利用解构函数,可以写出更加精简的表达式。

{ Point(0) => var y) => $ };

如果没有类型转换,则可以写得更加简单了:

string Display(Point o) => o { ( };

非空判断

如果只是判断空和非空,则有最简单的模式:

{ }  => o.ToString(),null => null"

Tuple patterns

也支持直接对ValueTuple进行模式匹配,用起来非常灵活。

static State ChangeState(State current,Transition transition,255);">bool hasKey) => (current,transition,hasKey) { (Opened,Close,_) => Closed,(Closed,Open,0);"> Opened,Lock,255);">true) => Locked,(Locked,Unlock,255);">true) =>new InvalidOperationException($Invalid transition) };

回到顶部

递归模式语句(recursive patterns)

现在可以这么写了(patterns 里可以包含 patterns)

IEnumerable<string> GetEnrollees()
{
    var p  People)
    {
        if (p is Student { Graduated: false,Name: string name })  name;
     }
 }

时间:2019-09-25 09:57:41 阅读(12)

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读