Unsafe 类
定义
重要
一些信息与预发行产品相关,相应产品在发行之前可能会进行重大修改。 对于此处提供的信息,Microsoft 不作任何明示或暗示的担保。
包含用于操作托管和非托管指针的通用低级别功能。
public ref class Unsafe abstract sealed
public static class Unsafe
type Unsafe = class
Public Class Unsafe
- 继承
-
Unsafe
注解
警告
此类型适用于高级指针操作方案。 假定调用方熟悉 ECMA-335、II.14.4 和 III.1.1.5 以及 ECMA-335 CLI 规范附录。
此类型上的大多数 API 不执行任何参数检查或验证。 错误使用这些 API 可能会损坏进程内存或破坏 .NET 运行时的稳定。
此类型通常由希望编写高性能代码并愿意禁止的低级别库作者使用。NET 的典型类型安全检查,以满足其性能目标。
请考虑以下示例,该示例反转 中的 Span<T>
元素。
注意
这些示例仅用于演示目的。 在实际应用程序中,开发人员应改用帮助程序函数(如 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 的正常安全检查,以提高自己的代码的性能。 此类开发人员通常依赖于静态分析工具或他们自己的代码评审来帮助强制实施正确性。 API Unsafe
允许开发人员使用不可验证的构造重写此代码,如以下示例所示。
// 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 漏洞、生成不正确的 codegen 或在 .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) |
返回一个值,该值指示指定的托管指针是否大于另一个指定的托管指针。 |
IsAddressLessThan<T>(T, T) |
返回一个值,该值指示指定的托管指针是否小于另一个指定的托管指针。 |
IsNullRef<T>(T) |
确定指向类型的 |
NullRef<T>() |
返回指向 类型的 |
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) |
将 类型的 |