C# 8 - Nullable Reference Types 可空引用类型html
从C# 8 开始,本地方法就能够是静态的了。 htm
与其余的本地方法不一样,静态的本地方法没法捕获任何本地状态量。 blog
直接看例子:
这段代码里有两个本地方法,他们分别对实例的一个字段和方法里的一个本地变量进行了修改操做,也就是捕获并更新了本地的状态。
其运行结果是:
能够看到类的成员字段和方法本地变量的状态都被这两个本地方法修改了。。
可是不少状况下,你并不但愿类的实例字段和方法本地变量的值被捕获或修改。在C# 8里面,你可使用静态本地方法来达到这个目的。
其作法很简单,就是在原来这两个本地方法前面加上static关键字便可:
能够看到程序报错了,这是由于静态本地方法是不能够访问和捕获实例的状态的,包括实例成员和方法本地变量。
针对第一个本地方法,我直接把更新本地变量的语句去掉:
而针对第二个本地方法,若是你真的想修改实例成员的状态,那么就须要把成员改成静态的:
其运行结果是:
C# 8的这个特性对可读性其实没有特别大的帮助,可是它却能够防止本地方法捕获实例状态,在一些状况下,这对性能有很大的帮助。
C# 7.2 里面出现了ref struct,可是它的缺点就是不能够实现接口。
看这个例子:
这个struct里面包含了一个不安全(unsafe)资源,当我用完以后,这个资源是须要被清理掉的。
在C# 8以前,咱们没法针对这个struct使用using语句,由于这个struct没法实现IDisposable接口。
可是从C# 8开始,ref struct无需实现IDisposable接口也可使用using语句或者using声明,只要它提供了适当的方法便可。以下图:
而后咱们就可使用using语句了:
或者using声明:
从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>仍然是托管的。
看例子。
在C# 8以前,咱们能够经过以下代码来保证numbers被初始化:
可是从C# 8开始,咱们能够更简单的表达咱们的意思:
这个特性带来的好处是,在变量名不是特别短小精悍的状况下,会少打不少字符。
C# 8里,针对内插逐字字符串的功能作了一点点加强。
在C# 8以前,这样写是没毛病的:
可是这样写就不行:
可是从C# 8开始,两种写法都是正确的:
都不会报错了。