How to Resolve Error "CS0244: Neither 'is' nor 'as' is valid on pointer types" in C#
The Compiler Error CS0244 is a type-safety restriction related to Unsafe Code. The message reads: "Neither 'is' nor 'as' is valid on pointer types".
In C#, the operators is and as are designed for safe type-checking and casting of Managed Types (classes, interfaces, nullable types, and boxed value types). They rely on runtime type information (RTTI) stored in the object header on the Managed Heap to function. Pointers (int*, void*, etc.) are unmanaged memory addresses. They do not have type headers, metadata, or runtime type information attached to them. Therefore, the managed type-checking operators cannot function on them.
This guide explains the distinction between managed casting and pointer casting and how to convert pointer types correctly.
Understanding is/as vs. Pointer Casting
obj is Type: Checks the runtime type header of an object.obj as Type: Checks the header and returns the object ornull.Pointer: A raw number representing a memory address (e.g.,0x00F2A1).
When you hold an int*, the system knows "I am pointing to an address," but it does not know if that address effectively contains an integer, a float, or garbage. Because there is no metadata to check, is and as are physically impossible operations. Pointers require Explicit Casting because you (the developer) are asserting knowledge that the compiler cannot verify.
Scenario 1: Using is with Pointers
This error occurs when a developer tries to verify if a generic pointer (void*) is actually a specific pointer type (like int*) using safe syntax.
Example of error:
public unsafe void CheckPointer(void* ptr)
{
// ⛔️ Error CS0244: Neither 'is' nor 'as' is valid on pointer types
// The runtime cannot look at a raw address 'ptr' and determine its type.
if (ptr is int*)
{
System.Console.WriteLine("It is an integer pointer.");
}
}
Scenario 2: Using as with Pointers
Similar to is, developers often try to use as to safely convert a pointer, expecting null if the types don't match. This is invalid because pointers cannot be type-checked safely.
Example of error:
public unsafe void ProcessData(void* data)
{
// ⛔️ Error CS0244: Neither 'is' nor 'as' is valid on pointer types.
// You cannot perform a "safe cast" on unmanaged memory.
int* intPtr = data as int*;
}
Solution: Explicit Pointer Casting
In unsafe contexts, you must use Explicit Casting syntax (Type). This tells the compiler: "Trust me, I know this memory address contains data of this type."
Fix for Casting
Use the parenthesis syntax (int*).
public unsafe void ProcessData(void* data)
{
// ✅ Correct: Explicit cast.
// WARNING: This does not "check" validity. It simply reinterprets the bits.
int* intPtr = (int*)data;
if (intPtr != null)
{
System.Console.WriteLine("Pointer converted.");
}
}
Fix for Type Checking (Logic Change)
Since you cannot check the type of a pointer at runtime, you usually need to pass an additional parameter (like an enum or Type object) to tell the method what kind of data the pointer holds.
public enum DataType { Int, Float }
public unsafe void CheckPointer(void* ptr, DataType type)
{
// ✅ Correct: Use external logic to determine how to cast.
if (type == DataType.Int)
{
int* intPtr = (int*)ptr;
System.Console.WriteLine("Processed as int.");
}
}
Conclusion
CS0244 reminds you that pointers are raw, dumb tools without the safety features of the .NET runtime.
- Stop using
is/as: These are for objects, not addresses. - Use Explicit Casts: Use
(int*)myPtrto convert types. - Manage Safety Manually: If you need to know the type of a
void*, you must track that information yourself; the pointer won't store it for you.