你可以在
结构类型
的声明中使用
ref
修饰符。
ref struct
类型的实例是在堆栈上分配的,不能转义到托管堆。 为了确保这一点,编译器将
ref struct
类型的使用限制如下:
ref struct
不能是数组的元素类型。
ref struct
不能是类或非
ref struct
的字段的声明类型。
ref struct
不能实现接口。
ref struct
不能被装箱为
System.ValueType
或
System.Object
。
ref struct
不能是类型参数。
ref struct
变量不能由
Lambda 表达式
或
本地函数
捕获。
ref struct
变量不能在
async
方法中使用。 但是,可以在同步方法中使用
ref struct
变量,例如,在返回
Task
或
Task<TResult>
的方法中。
ref struct
变量不能在
迭代器
中使用。
可以定义一次性的
ref struct
。 为此,请确保
ref struct
符合
一次性模式
。 也就是说,它有一个实例
Dispose
方法,该方法是可访问、无参数的并且具有
void
返回类型。 可以将
using 语句或声明
与可释放的
ref struct
的实例一起使用。
通常,如果需要一种同时包含
ref struct
类型的数据成员的类型,可以定义
ref struct
类型:
public ref struct CustomRef
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
若要将
ref struct
声明为
readonly
,请在类型声明中组合使用
readonly
修饰符和
ref
修饰符(
readonly
修饰符必须位于
ref
修饰符之前):
public readonly ref struct ConversionRequest
public ConversionRequest(double rate, ReadOnlySpan<double> values)
Rate = rate;
Values = values;
public double Rate { get; }
public ReadOnlySpan<double> Values { get; }
在 .NET 中,
ref struct
的示例分别是
System.Span<T>
和
System.ReadOnlySpan<T>
。
ref
字段
从 C# 11 开始,可以在
ref struct
中声明
ref
字段,如以下示例所示:
public ref struct RefFieldExample
private ref int number;
public int GetNumber()
if (System.Runtime.CompilerServices.Unsafe.IsNullRef(ref number))
throw new InvalidOperationException("The number ref field is not initialized.");
return number;
ref
字段可能具有
null
值。 使用
Unsafe.IsNullRef<T>(T)
方法确定
ref
字段是否为
null
。
可通过以下方式将
readonly
修饰符应用于
ref
字段:
readonly ref
:只能在构造函数或
init
访问器
中使用
= ref
运算符
通过 ref 重新赋值
此类字段。 可以在字段访问修饰符允许的任何时间点使用
=
运算符分配值。
ref readonly
:在任何时候,都不能使用
=
运算符为此类字段赋值。 但是,可以使用
= ref
运算符通过 ref 重新赋值字段。
readonly ref readonly
:只能在构造函数或
init
访问器中通过 ref 重新赋值此类字段。 在任何时候,都不能为字段赋值。
编译器确保存储在
ref
字段中的引用的生存期不会超过它引用的值。 有关范围规则的信息,请参阅
方法参数
一文的
引用和值的范围
部分。
C# 语言规范
有关详细信息,请参阅
C# 语言规范
中的
结构
部分。
有关 C#7.2 及更高版本中引入的功能的更多信息,请参见以下功能建议说明:
C# 7.2 - 类 ref 类型的编译时安全性
C# 11 - ref 字段和 scoped
C# 参考
C# 类型系统