Unsafe.As Method

Definition

Overloads

As<T>(Object)

Casts the given object to the specified type.

As<TFrom,TTo>(TFrom)

Reinterprets the given managed pointer as a new managed pointer to a value of type TTo.

As<T>(Object)

Casts the given object to the specified type.

public:
generic <typename T>
 where T : class static T As(System::Object ^ o);
public static T As<T> (object o) where T : class;
public static T? As<T> (object? o) where T : class;
static member As : obj -> 'T (requires 'T : null)
Public Shared Function As(Of T As Class) (o As Object) As T

Type Parameters

T

The type which the object will be cast to.

Parameters

o
Object

The object to cast.

Returns

T

The original object, cast to the given type.

Remarks

This API is used to cast an object to the given type, suppressing the runtime's normal type safety checks. It is the caller's responsibility to ensure that the cast is legal. No InvalidCastException will be thrown.

The behavior of Unsafe.As<T>(o) is only well-defined if the typical "safe" casting operation (T)o would have succeeded. Use of this API to circumvent casts that would otherwise have failed is unsupported and could result in runtime instability.

To help enforce correct usage, developers might consider using a standard cast or a debug-only assert in their code, as shown in the following examples.

void ReinterpretCastAndUse_Sample1(object o)
{
  // Assume that we know through some other means that 'o' is a string,
  // and we want our library's debug builds to verify this.
  // One way to do this is through a standard-style cast.
  // A standard-style cast will throw InvalidCastException at runtime if the cast fails.
  // n.b. Casts of null objects to reference types will succeed.

#if DEBUG
  string s = (string)o;
#else
  string s = Unsafe.As<string>(o);
#endif

  DoSomethingWith(s);
}

void ReinterpretCastAndUse_Sample2(object o)
{
  // Another way to check this is through a debug-only assert.
  // Failed assertions will trigger attached debuggers or terminate the application immediately.
  // Calls to Debug.Assert are removed from release builds.

  Debug.Assert(o is null or string, "Unsafe.As call below is illegal!");
  string s = Unsafe.As<string>(o);

  DoSomethingWith(s);
}

Applies to

As<TFrom,TTo>(TFrom)

Reinterprets the given managed pointer as a new managed pointer to a value of type TTo.

public:
generic <typename TFrom, typename TTo>
 static TTo % As(TFrom % source);
public static ref TTo As<TFrom,TTo> (ref TFrom source);
static member As : 'From -> 'o
Public Shared Function As(Of TFrom, TTo) (ByRef source As TFrom) As TTo

Type Parameters

TFrom

The type of managed pointer to reinterpret.

TTo

The desired type of the managed pointer.

Parameters

source
TFrom

The managed pointer to reinterpret.

Returns

TTo

A managed pointer to a value of type TTo.

Remarks

This API is conceptually similar to C++'s reinterpret_cast<>. It is the caller's responsibility to ensure that the cast is legal. No runtime check will be performed.

Only the managed pointer is reinterpreted. The referenced value itself will remain unchanged. Consider the following example.

int[] intArray = new int[] { 0x1234_5678 }; // a 1-element array
ref int refToInt32 = ref intArray[0]; // managed pointer to first Int32 in array
ref short refToInt16 = ref Unsafe.As<int, short>(ref refToInt32); // reinterpret as managed pointer to Int16
Console.WriteLine($"0x{refToInt16:x4}");

The output of this program depends on the endianness of the current machine. On big-endian architectures, this code outputs 0x1234. On little-endian architectures, this code outputs 0x5678.

When casting a managed pointer from a narrower type to a wider type, the caller must ensure that dereferencing the pointer will not incur an out-of-bounds access. The caller is also responsible for ensuring that the resulting pointer is properly aligned for the referenced type. For more information on alignment assumptions, see ECMA-335, Sec. I.12.6.2 ("Alignment").

Applies to