前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C# 8 - 其它新特性

C# 8 - 其它新特性

作者头像
solenovex
发布2019-11-07 14:35:25
8370
发布2019-11-07 14:35:25
举报
文章被收录于专栏:草根专栏草根专栏

其它关于C# 8和.NET Core 3.0新特性的文章:

C# 8 - Nullable Reference Types 可空引用类型

C# 8 - 模式匹配

C# 8 - Range 和 Index(范围和索引)

C# 8.0 - 默认接口方法

C# 8 - using声明 和 异步流

.NET Core 3.0 里新的JSON API

.NET Core 3.0 本地工具

.NET Core 3.0 构建和部署

静态本地方法

从C# 8 开始,本地方法就可以是静态的了。

与其他的本地方法不同,静态的本地方法无法捕获任何本地状态量。

直接看例子:

这段代码里有两个本地方法,他们分别对实例的一个字段和方法里的一个本地变量进行了修改操作,也就是捕获并更新了本地的状态。

其运行结果是:

可以看到类的成员字段和方法本地变量的状态都被这两个本地方法修改了。。

但是很多情况下,你并不希望类的实例字段和方法本地变量的值被捕获或修改。在C# 8里面,你可以使用静态本地方法来达到这个目的。

其做法很简单,就是在原来这两个本地方法前面加上static关键字即可:

可以看到程序报错了,这是因为静态本地方法是不可以访问和捕获实例的状态的,包括实例成员和方法本地变量。

针对第一个本地方法,我直接把更新本地变量的语句去掉:

而针对第二个本地方法,如果你真的想修改实例成员的状态,那么就需要把成员改为静态的:

其运行结果是:

优点

C# 8的这个特性对可读性其实没有特别大的帮助,但是它却可以防止本地方法捕获实例状态,在一些情况下,这对性能有很大的帮助。

Disposable ref Structs

C# 7.2 里面出现了ref struct,但是它的缺点就是不可以实现接口。

看这个例子:

这个struct里面包含了一个不安全(unsafe)资源,当我用完之后,这个资源是需要被清理掉的。

在C# 8之前,我们无法针对这个struct使用using语句,因为这个struct无法实现IDisposable接口。

但是从C# 8开始,ref struct无需实现IDisposable接口也可以使用using语句或者using声明,只要它提供了适当的方法即可。如下图:

然后我们就可以使用using语句了:

或者using声明:

只读struct成员

从C# 8开始,我们可以在struct的成员上使用readonly修饰符。

为struct的成员添加readonly修饰符就表示告诉编译器和开发者该成员不可以修改struct的状态。

看下面这个例子:

这里的ToString()方法不会修改Point这个struct的状态,所以我们可以在该方法上添加readonly修饰符来表示其只读:

但是这里会出现警告,因为 ToString 访问了未标记为 readonly 的 Distance 属性。也就是需要创建防御性副本时,编译器会发出警告。

由于Distance属性不会修改状态,所以可以在它前边加上readonly修饰符以修复此警告:

请注意,readonly 修饰符对于只读属性是必须要添加的。 编译器会假设 get 访问器可以修改状态;所以必须显式声明 readonly。

但是自动实现的属性则是一个例外;编译器将所有自动实现的 Getter 视为 readonly,因此,此处无需向 X 和 Y 属性添加 readonly 修饰符。

如果我在该struct里面再添加一个修改状态的方法:

由于该方法确实修改了struct的状态,所以如果在该方法上再加上readonly修饰符的话,编译器就会报错。

而如果我把readonly修饰符去掉的话,那么就不会报错了:

非托管构造类型

在C#里面,类型可以分为托管类型和非托管类型。在之前的.NET版本中,只有内置的值类型、枚举类型和仅包含非托管类型成员的struct等这些类型才可以是非托管类型。其中内置的值类型有:

  • byte
  • int
  • char
  • float
  • bool

而构造类型(指包含至少一个类型参数的类型)不能为非托管类型。

看下面这个泛型struct:

在C# 7里,无论这里的T是int还是object,该类型都不可以是非托管类型,即使T是一个非托管类型。

而在C# 8里,如果构造类型的所有类型参数都是非托管类型的,那么这个构造类型就是非托管的。

所以Coords<int> 类型在 C# 8.0 及更高版本中是非托管类型。但是Coords<object>仍然是托管的。

Null 合并赋值

看例子。

在C# 8之前,我们可以通过如下代码来保证numbers被初始化:

但是从C# 8开始,我们可以更简单的表达我们的意思:

这个特性带来的好处是,在变量名不是特别短小精悍的情况下,会少打很多字符。

内插逐字字符串的增强功能

C# 8里,针对内插逐字字符串的功能做了一点点增强。

在C# 8之前,这样写是没毛病的:

但是这样写就不行:

但是从C# 8开始,两种写法都是正确的:

都不会报错了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-11-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 其它关于C# 8和.NET Core 3.0新特性的文章:
  • 静态本地方法
    • 优点
    • Disposable ref Structs
    • 只读struct成员
    • Null 合并赋值
    • 内插逐字字符串的增强功能
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档