请注意,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之前,这样写是没毛病的: