ref
Типы структур (справочник по C#)
Модификатор можно использовать ref
в объявлении типа структуры. Экземпляры ref struct
типа выделяются в стеке и не могут экранироваться в управляемую кучу. Чтобы убедиться, что компилятор ограничивает использование ref struct
типов следующим образом:
- Не
ref struct
может быть типом элемента массива. - Не
ref struct
может быть объявленным типом поля класса или не-ref struct
. - Не
ref struct
удается реализовать интерфейсы. - Не
ref struct
удается включить System.ValueType в поле или System.Object. - Аргумент
ref struct
типа не может быть аргументом типа. - Переменная
ref struct
не может быть захвачена лямбда-выражениемили локальной функцией. - Переменная
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
поле в виде ref struct
следующего примера:
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) Используйте метод, чтобы определить, является null
ли ref
поле.
Модификатор можно применить к ref
полю readonly
следующим образом:
readonly ref
: можно переназначить такое поле= ref
только в конструкторе или методеinit
доступа. Можно назначить значение оператору=
в любой точке, разрешенной модификатором доступа к полю.ref readonly
: в любой момент нельзя назначить значение оператору=
для такого поля. Однако можно переназначить поле оператором= ref
.readonly ref readonly
: можно переназначить такое поле только в конструкторе или методеinit
доступа. В любой момент нельзя назначить значение полю.
Компилятор гарантирует, что ссылка, хранящуюся в ref
поле, не выходит за пределы его ссылки.
Функция ref
полей обеспечивает безопасную реализацию таких типов:System.Span<T>
public readonly ref struct Span<T>
{
internal readonly ref T _reference;
private readonly int _length;
// Omitted for brevity...
}
Тип Span<T>
сохраняет ссылку, через которую он обращается к смежным элементам в памяти. Использование ссылки позволяет Span<T>
экземпляру избежать копирования хранилища, на которое он ссылается.
Спецификация языка C#
Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:
Дополнительные сведения о ref
полях см. в заметке о улучшении структуры низкого уровня.
См. также
Обратная связь
https://aka.ms/ContentUserFeedback.
Ожидается в ближайшее время: в течение 2024 года мы постепенно откажемся от GitHub Issues как механизма обратной связи для контента и заменим его новой системой обратной связи. Дополнительные сведения см. в разделеОтправить и просмотреть отзыв по