C产品在市场上有哪些独特优势?

2026-04-29 06:032阅读0评论SEO基础
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1308个文字,预计阅读时间需要6分钟。

C产品在市场上有哪些独特优势?

目录 + 可空引用类型(Nullable reference types) + 异步流(Async streams) + 范围和下标类型(Ranges and indices) + 模式匹配表达式(Switch expressions) + Switch表达式 + 属性模式 + 位置模式 + 非空判断

目录

C产品在市场上有哪些独特优势?

  • 可空引用类型(Nullable reference types)
  • 异步流(Async streams)
  • 范围和下标类型(Ranges and indices)
  • 模式匹配表达式(Switch expressions )
    • Switch表达式
    • Property patterns
    • Positional patterns
    • 非空判断
    • Tuple patterns
  • 递归模式语句(recursive patterns)



使用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 > 20) return result; else return -1; } async IAsyncEnumerable<int> GetBigResultsAsync() { await foreach (var result in GetResultsAsync()) { if (result > 20) yield return result; } } 回到顶部

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

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

Index i1 = 3; // 下标为 3 Index i2 = ^4; // 倒数第 4 个元素 int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 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; } 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 == 0 && p.Y == 0: return "origin"; case Point p: return $"({p.X}, {p.Y})"; default: return "unknown"; } }

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

Switch表达式

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

static string Display(object o) => o switch { Point p when p.X == 0 && p.Y == 0 => "origin", Point p => $"({p.X}, {p.Y})", _ => "unknown" };

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

Property patterns

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

static string Display(object o) => o switch { Point { X: 0, Y: 0 } => "origin", Point p => $"({p.X}, {p.Y})", _ => "unknown" };

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

static string Display(object o) => o switch { Point { X: 0, Y: 0 } => "origin", Point { X: var x, Y: var y } => $"({x}, {y})", _ => "unknown" };

Positional patterns

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

static string Display(object o) => o switch { Point(0, 0) => "origin", Point(var x, var y) => $"({x}, {y})", _ => "unknown" };

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

static string Display(Point o) => o switch { (0, 0) => "origin", (var x, var y) => $"({x}, {y})" };

非空判断

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

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

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; } } 时间:2019-09-25 09:57:41 阅读(12)

本文共计1308个文字,预计阅读时间需要6分钟。

C产品在市场上有哪些独特优势?

目录 + 可空引用类型(Nullable reference types) + 异步流(Async streams) + 范围和下标类型(Ranges and indices) + 模式匹配表达式(Switch expressions) + Switch表达式 + 属性模式 + 位置模式 + 非空判断

目录

C产品在市场上有哪些独特优势?

  • 可空引用类型(Nullable reference types)
  • 异步流(Async streams)
  • 范围和下标类型(Ranges and indices)
  • 模式匹配表达式(Switch expressions )
    • Switch表达式
    • Property patterns
    • Positional patterns
    • 非空判断
    • Tuple patterns
  • 递归模式语句(recursive patterns)



使用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 > 20) return result; else return -1; } async IAsyncEnumerable<int> GetBigResultsAsync() { await foreach (var result in GetResultsAsync()) { if (result > 20) yield return result; } } 回到顶部

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

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

Index i1 = 3; // 下标为 3 Index i2 = ^4; // 倒数第 4 个元素 int[] a = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 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; } 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 == 0 && p.Y == 0: return "origin"; case Point p: return $"({p.X}, {p.Y})"; default: return "unknown"; } }

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

Switch表达式

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

static string Display(object o) => o switch { Point p when p.X == 0 && p.Y == 0 => "origin", Point p => $"({p.X}, {p.Y})", _ => "unknown" };

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

Property patterns

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

static string Display(object o) => o switch { Point { X: 0, Y: 0 } => "origin", Point p => $"({p.X}, {p.Y})", _ => "unknown" };

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

static string Display(object o) => o switch { Point { X: 0, Y: 0 } => "origin", Point { X: var x, Y: var y } => $"({x}, {y})", _ => "unknown" };

Positional patterns

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

static string Display(object o) => o switch { Point(0, 0) => "origin", Point(var x, var y) => $"({x}, {y})", _ => "unknown" };

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

static string Display(Point o) => o switch { (0, 0) => "origin", (var x, var y) => $"({x}, {y})" };

非空判断

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

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

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; } } 时间:2019-09-25 09:57:41 阅读(12)