C# 版本 7.2 新增特性

发布时间:2017 年 11 月

C# 7.2 版添加了几个小型语言功能:

  • stackalloc 数组上的初始值设定项。
  • 对支持模式的任何类型使用 fixed 语句。
  • 无需固定即可访问固定的字段。
  • 重新分配 ref 本地变量。
  • 声明 readonly struct 类型,以指示结构不可变且应作为 in 参数传递到其成员方法。
  • 在实参上添加 in 修饰符,以指定形参通过引用传递,但不通过调用方法修改。
  • 对方法返回项使用 ref readonly 修饰符,以指示方法通过引用返回其值,但不允许写入该对象。
  • 声明 ref struct 类型,以指示结构类型直接访问托管的内存,且必须始终分配有堆栈。
  • 使用其他泛型约束。
  • 非尾随命名参数
    • 位置参数可以跟在命名参数后面。
  • 数值文本中的前导下划线:
    • 数值文字现可在任何打印数字前放置前导下划线。
  • private protected 访问修饰符
    • private protected 访问修饰符允许访问同一程序集中的派生类。
  • 条件 ref 表达式:
    • 现在可以引用条件表达式 (?:) 的结果。

参考文章:
C#7.2 新增功能 - 张传宁 - 博客园
C#7.2 新增功能-CSDN博客


笔记

网上对于本版本新增的特性与官网描述的有出入,以参考文章为准。

安全高效的代码的增强功能

利用7.2中引入的语言功能,可在使用引用语义时处理值类型。它们旨在尽量减少值类型的复制。而不造成与引用类型使用相关的内存分配,进而提升性能。功能包括:

针对实参的 in 修饰符,指示形参通过引用传递,但不通过调用方法修改。将 in 修改符添加到参数是 源兼容的更改

void Foo(SomeType Param){...}
// 调用
SomeType x = ...;
Foo(in x);

// 说明:方法中的参数会**按引用传入**
// 如果没有方法的重载,在调用方法时,in 修饰符是可以省略的
// 与 ref 有点类似,但:被 in 关键字修饰的参数是只读的,在方法内部是不可更改的
// 方法中的参数默认是按值传递的(复制了一个副本),按引用传递则减少了复制副本的开销

针对方法的返回 ref readonly 修饰符,指示方法通过引用返回类型,但不允许写入该对象。如果向某个值赋予返回值,则添加 ref readonly 修饰符是 源兼容的更改。将 readonly 修饰符添加到现有的 ref 返回语句是 不兼容的更改。它要求调用方 ref 本地变量的声明以包含 readonly修饰符。

static ref readonly string Prop => ref x;

// ref x: 表示引用返回值 ❓返回的是值的引用还不是实际值?❓有啥优点?
// ref readonly 在保持引用返回的同时防止了修改

readonly struct 声明,指示结构不可变,且应作为 in 参数传递到其成员方法。将 readonly 修饰符添加到现有的结构声明是 二进制兼容的更改

ref struct 声明,指示结构类型直接访问托管的内存,且必须始终分配有堆栈。将 ref 修饰符添加到现有 struct 声明是 不兼容的更改ref struct 不能是类的成员,也不能用于可在堆上分配的其他位置。

非尾随命名参数

的使用命名参数的时候可不按顺序传参。

数值文字中的前导下划线

C# 7.0 中实现了对数字分隔符的支持,但这不允许文字值的第一个字符是 _。 十六进制文本和二进制文件现可以 _ 开头。例如:

int binaryValue = 0b_0101_0101;

private protected 访问修饰符

private protected 是 internal 与 protected 的交集。

新的复合访问修饰符:private protected 指示可通过包含同一程序集中声明的类或派生类来访问成员。 虽然 protected internal 允许通过同一程序集中的类或派生类进行访问,但 private protected 限制对同一程序集中声明的派生类的访问。


可使用访问修饰符指定以下 7 个可访问性级别:

  • public:访问不受限制。
  • protected:访问限于包含类或派生自包含类的类型。
  • internal:访问限于当前程序集。
  • protected internal:访问限于当前程序集或派生自包含类的类型。
  • private:访问限于包含类。
  • private protected:访问限于包含类或当前程序集中派生自包含类的类型。
  • file:已声明的类型仅在当前源文件中可见。 文件范围的类型通常用于源生成器。

条件 ref 表达式

条件表达式可能生成 ref 结果而不是值。 例如,你将编写以下内容以检索对两个数组之一中第一个元素的引用:

ref var r = ref (arr != null ? ref arr[0] : ref otherArr[0]);

变量 r 是对 arr 或 otherArr 中第一个值的引用。

posted @ 2025-02-05 17:49  石起起  阅读(72)  评论(0)    收藏  举报