Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
ref Используйте модификатор при объявлении типа структуры. Вы выделяете экземпляры ref struct типа в стеке, и они не могут экранироваться в управляемую кучу. Чтобы обеспечить это свойство, компилятор ограничивает использование ref struct типов следующим образом:
- Нельзя использовать
ref structв качестве типа элемента массива. - Нельзя объявить
ref structв качестве типа поля в классе или не-ref struct. - Вы не можете ставить поле для
ref structили System.ValueTypeSystem.Object. - Невозможно записать
ref structпеременную в лямбда-выражении или локальной функции. - До C# 13 нельзя использовать
ref structпеременные в методеasync. Начиная с C# 13 переменнаяref structне может использоваться в том же блоке, чтоawaitи выражение в методеasync. Однако переменные можно использоватьref structв синхронных методах, например в методах, возвращающих Task или Task<TResult>. - До C# 13 нельзя использовать переменную
ref structв итераторах. Начиная с C# 13,ref structтипы иrefлокальные типы можно использовать в итераторах, если они не содержатся в сегментах кода с инструкциейyield return. - До C# 13
ref structне удается реализовать интерфейсы. Начиная с C# 13 структураrefможет реализовывать интерфейсы, но должна соответствовать правилам безопасности ссылок . Например, тип нельзя преобразовать в тип интерфейса,ref structтак как для этого требуется преобразование бокса. - До C# 13
ref structне может быть аргументом типа. Начиная с C# 13, аргумент типа может быть аргументом типа,ref structесли параметр типа указываетallows ref structв предложении.where
Справочные документы на языке C#, выпущенные последней версией языка C#. Она также содержит начальную документацию по функциям в общедоступных предварительных версиях для предстоящего языкового выпуска.
Документация определяет любую функцию, впервые представленную в последних трех версиях языка или в текущих общедоступных предварительных версиях.
Подсказка
Чтобы узнать, когда функция впервые появилась в C#, ознакомьтесь со статьей по журналу версий языка C#.
Как правило, вы определяете ref struct тип, если требуется тип, который также включает элементы ref struct данных типов:
public ref struct CustomRef
{
public bool IsValid;
public Span<int> Inputs;
public Span<int> Outputs;
}
Чтобы объявить как ref structreadonly, объедините 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 Поля
Вы можете объявить 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) Используйте метод, чтобы определить, является refли null поле.
Модификатор можно применить к readonly полю ref следующим образом:
-
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> экземпляр избегает копирования хранилища, на который он ссылается.
Шаблон, допускающий удаление
Можно определить утилизированную ref struct. Для этого убедитесь, что ref struct шаблон подходит для удаления. То есть он имеет метод экземпляра Dispose , который доступен, без параметров и имеет тип возвращаемого void значения. Вы можете использовать инструкцию using или объявление с экземпляром удаленного объекта ref struct.
Начиная с C# 13, можно также реализовать IDisposableref struct типы. Однако разрешение перегрузки предпочитает уменяемый шаблон для метода интерфейса. Компилятор разрешает IDisposable.Dispose метод только в том случае, если подходящий Dispose метод не найден.
Ограничения для ref struct типов, реализующих интерфейс
Эти ограничения гарантируют, что ref struct тип, реализующий интерфейс, соответствует необходимым правилам безопасности ссылок .
- Невозможно преобразовать
ref structэкземпляр интерфейса, который он реализует. Это ограничение включает неявное преобразование при использованииref structтипа в качестве аргумента, а параметр — тип интерфейса. Преобразование приводит к преобразованию бокса, которое нарушает безопасность ссылок.ref structможет объявлять методы как явные объявления интерфейса. Однако доступ к этим методам можно получить только из универсальных методов, в которых типы параметровallows ref structтипа. -
ref struct, реализующий интерфейс , должен реализовать все экземплярные члены интерфейса.ref structдолжен реализовывать членов экземпляра, даже если интерфейс включает реализацию по умолчанию.
Компилятор применяет эти ограничения. При написании ref struct типов, реализующих интерфейсы, каждое новое обновление может включать новые члены интерфейса по умолчанию. Пока вы не предоставите реализацию для любых новых методов экземпляра, приложение не компилируется. Нельзя предоставить конкретную реализацию для метода интерфейса static с реализацией по умолчанию.
Внимание
Реализация интерфейса с типом ref struct представляет потенциал для последующих критических и двоичных изменений. Разрыв возникает, если ref struct интерфейс, определенный в другой сборке, и эта сборка предоставляет обновление, которое добавляет элементы по умолчанию в этот интерфейс.
Исходный разрыв происходит при повторной компиляции ref struct: он должен реализовать новый член, даже если существует реализация по умолчанию.
Двоичный разрыв происходит при обновлении внешней сборки без повторной компиляции ref struct типа , а обновленный код вызывает реализацию нового метода по умолчанию. Среда выполнения создает исключение при доступе к члену по умолчанию.
Спецификация языка C#
Дополнительные сведения см. в следующих разделах статьи Спецификация языка C#:
Дополнительные сведения о ref полях см. в заметке о улучшении структуры низкого уровня.