Unsafe 클래스
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
관리되는 포인터와 관리되지 않는 포인터를 조작하기 위한 일반 하위 수준 기능이 포함되어 있습니다.
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 및 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의 정상적인 안전 검사를 수행합니다. 이러한 개발자는 일반적으로 정적 분석 도구 또는 자체 코드 검토를 사용하여 정확성을 적용합니다.
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));
}
}
API는 Unsafe
일반적인 형식 안전 유효성 검사를 표시하지 않으므로 작성 중인 코드가 합법적인지 확인하는 것은 호출자에게 달려 있습니다. 이러한 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>() |
형식의 값에 대한 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) |
boxed 값에 대해 |
Write<T>(Void*, T) |
지정된 위치에 형식 |
WriteUnaligned<T>(Byte, T) |
대상 주소의 아키텍처 종속 맞춤을 가정하지 않고 지정된 위치에 형식 |
WriteUnaligned<T>(Void*, T) |
대상 주소의 아키텍처 종속 맞춤을 가정하지 않고 지정된 위치에 형식 |
적용 대상
.NET