Unsafe Класс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Содержит универсальные, низкоуровневые функции для управления управляемыми и неуправляемыми указателями.
public ref class Unsafe abstract sealed
public static class Unsafe
type Unsafe = class
Public Class Unsafe
- Наследование
-
Unsafe
Комментарии
Предупреждение
Этот тип предназначен для сценариев расширенной манипуляции указателем. Предполагается, что вызывающие абоненты знакомы с ECMA-335, Sec. II.14.4 и III.1.1.5 и надстройкой спецификации CLI ECMA-335.
Большинство API этого типа не выполняют проверку аргументов или проверку. Неправильное использование этих API может повредить память процесса или дестабилизировать среду выполнения .NET.
Этот тип обычно используется авторами библиотек низкого уровня, которые хотят писать код высокой производительности и готовы подавлять типичные проверки безопасности типов .NET для удовлетворения своих целей производительности.
Рассмотрим следующий пример, который изменяет элементы внутри Span<T>.
Note
Эти примеры существуют просто для демонстрационных целей. В реальных приложениях разработчики должны вместо этого использовать вспомогательные функции, такие как Reverse, которые лучше оптимизированы, чем даже эти примеры.
// A safe, verifiable way to reverse a Span<T>.
static void Reverse<T>(Span<T> span)
{
while (span.Length > 1)
{
T firstElement = span[0];
T lastElement = span[^1];
span[0] = lastElement;
span[^1] = firstElement;
span = span[1..^1];
}
}
Этот метод полностью типобезопасн и среда выполнения .NET может вставлять проверки границ, чтобы обеспечить безопасность. Однако авторам библиотек низкого уровня может потребоваться отключить обычные проверки безопасности .NET, чтобы повысить производительность собственного кода. Такие разработчики обычно полагаются на статические средства анализа или собственные проверки кода, чтобы обеспечить правильность.
Unsafe API позволяют разработчику переписать этот код с помощью непроверяемых конструкций, как показано в следующем примере.
// A correct but unverifiable way to reverse a Span<T>.
static void Reverse<T>(Span<T> span)
{
if (span.Length > 1)
{
ref T refLeft = ref MemoryMarshal.GetReference(span);
ref T refRight = ref Unsafe.Add(ref refLeft, span.Length - 1);
do
{
T leftElement = refLeft;
T rightElement = refRight;
refLeft = rightElement;
refRight = leftElement;
refLeft = ref Unsafe.Add(ref refLeft, 1);
refRight = ref Unsafe.Subtract(ref refRight, 1);
} while (Unsafe.IsAddressLessThan(ref refLeft, ref refRight));
}
}
Unsafe Так как API подавляют типичную проверку безопасности типов, это позволяет вызывающим системам гарантировать, что код, который они пишут, является законным. Неправильное использование этих API может привести к нарушениям доступа, созданию отверстий GC, созданию неправильного кодегена или в противном случае вызвать неопределенное и дестабилизирующее поведение в среде выполнения .NET.
Методы
| Имя | Описание |
|---|---|
| Add<T>(T, Int32) |
Добавляет смещение в заданный управляемый указатель. |
| Add<T>(T, IntPtr) |
Добавляет смещение элемента в заданный управляемый указатель. |
| Add<T>(T, UIntPtr) |
Добавляет смещение элемента в заданный управляемый указатель. |
| Add<T>(Void*, Int32) |
Добавляет смещение элемента в заданный неуправляемый указатель. |
| AddByteOffset<T>(T, IntPtr) |
Добавляет смещение байтов в заданный управляемый указатель. |
| AddByteOffset<T>(T, UIntPtr) |
Добавляет смещение байтов в заданный управляемый указатель. |
| AreSame<T>(T, T) |
Определяет, указывают ли указанные управляемые указатели на то же расположение. |
| As<T>(Object) |
Приведение заданного объекта к указанному типу. |
| As<TFrom,TTo>(TFrom) |
Повторно интерпретирует заданный управляемый указатель как новый управляемый указатель на значение типа |
| AsPointer<T>(T) |
Преобразует управляемый указатель в неуправляемый указатель. |
| AsRef<T>(T) |
Повторно интерпретирует указанную ссылку только для чтения в качестве изменяемой ссылки. |
| AsRef<T>(Void*) |
Преобразует неуправляемый указатель в управляемый указатель на значение типа |
| BitCast<TFrom,TTo>(TFrom) |
Повторно интерпретирует заданное значение типа |
| ByteOffset<T>(T, T) |
Определяет смещение байтов от источника к целевому объекту с заданных управляемых указателей. |
| Copy<T>(T, Void*) |
Копирует значение типа |
| Copy<T>(Void*, T) |
Копирует значение типа |
| CopyBlock(Byte, Byte, UInt32) |
Копирует байты из исходного адреса в целевой адрес. |
| CopyBlock(Void*, Void*, UInt32) |
Копирует байты из исходного адреса в целевой адрес. |
| CopyBlockUnaligned(Byte, Byte, UInt32) |
Копирует байты из исходного адреса в целевой адрес, не предполагая, что архитектура зависит от выравнивания адресов. |
| CopyBlockUnaligned(Void*, Void*, UInt32) |
Копирует байты из исходного адреса в целевой адрес, не предполагая, что архитектура зависит от выравнивания адресов. |
| InitBlock(Byte, Byte, UInt32) |
Инициализирует блок памяти в заданном расположении с заданным начальным значением. |
| InitBlock(Void*, Byte, UInt32) |
Инициализирует блок памяти в заданном расположении с заданным начальным значением. |
| InitBlockUnaligned(Byte, Byte, UInt32) |
Инициализирует блок памяти в заданном расположении с заданным начальным значением, не предполагая выравнивание архитектуры, зависящей от адреса. |
| InitBlockUnaligned(Void*, Byte, UInt32) |
Инициализирует блок памяти в заданном расположении с заданным начальным значением, не предполагая выравнивание архитектуры, зависящей от адреса. |
| IsAddressGreaterThan<T>(T, T) |
Возвращает значение, указывающее, больше ли указанного управляемого указателя, чем другой указанный управляемый указатель. |
| IsAddressGreaterThanOrEqualTo<T>(T, T) |
Определяет, является ли адрес памяти, на который ссылается ссылка, |
| IsAddressLessThan<T>(T, T) |
Возвращает значение, указывающее, меньше ли указанного управляемого указателя, чем другой указанный управляемый указатель. |
| IsAddressLessThanOrEqualTo<T>(T, T) |
Определяет, равен ли адрес памяти, на который ссылается ссылка |
| IsNullRef<T>(T) |
Определяет, является ли заданный управляемый указатель значением типа |
| NullRef<T>() |
Возвращает управляемый указатель null на значение типа |
| Read<T>(Void*) |
Считывает значение типа |
| ReadUnaligned<T>(Byte) |
Считывает значение типа |
| ReadUnaligned<T>(Void*) |
Считывает значение типа |
| SizeOf<T>() |
Возвращает размер значения заданного параметра типа. |
| SkipInit<T>(T) |
Проходит определенные правила назначения для заданной ссылки. |
| Subtract<T>(T, Int32) |
Вычитает смещение из заданного управляемого указателя. |
| Subtract<T>(T, IntPtr) |
Вычитает смещение элемента из заданного управляемого указателя. |
| Subtract<T>(T, UIntPtr) |
Вычитает смещение элемента из заданного управляемого указателя. |
| Subtract<T>(Void*, Int32) |
Вычитает смещение элемента из заданного неуправляемого указателя. |
| SubtractByteOffset<T>(T, IntPtr) |
Вычитает смещение байтов из заданного управляемого указателя. |
| SubtractByteOffset<T>(T, UIntPtr) |
Вычитает смещение байтов из заданного управляемого указателя. |
| Unbox<T>(Object) |
|
| Write<T>(Void*, T) |
Записывает значение типа |
| WriteUnaligned<T>(Byte, T) |
Записывает значение типа |
| WriteUnaligned<T>(Void*, T) |
Записывает значение типа |