How to Resolve Error "CS0077: The as operator must be used with a reference type or nullable type" in C#
The Compiler Error CS0077 is a type safety error involving the as operator. The message reads: "The as operator must be used with a reference type or nullable type ('int' is a non-nullable value type)."
The as operator is known as the "safe cast" operator. It attempts to convert an object to a specific type, and if the conversion fails, it returns null.
This error occurs because you are trying to cast to a non-nullable value type (like int, bool, double, or a struct). These types technically cannot hold a null value. Since the as operator's fail-safe mechanism relies on returning null, it physically cannot work with types that don't accept null.
Understanding the 'as' Operator logic
The syntax x as T roughly translates to:
"Check if x is compatible with type T. If yes, return it as T. If no, return null."
- Reference Types (
string,class): Can benull. Theasoperator works. - Nullable Value Types (
int?,bool?): Can benull. Theasoperator works. - Value Types (
int,bool): Cannot benull. Theasoperator fails with CS0077.
Scenario 1: Casting to Primitive Types
The most common mistake is trying to safely extract a number or boolean from an object using as.
Example of error:
public void ProcessData(object input)
{
// input might be an integer, or it might be a string, or null.
// ⛔️ Error CS0077: 'int' is a non-nullable value type.
// If 'input' is NOT an integer, 'as' wants to return null.
// But 'number' (int) cannot hold null.
int number = input as int;
}
Solution 1: Use Nullable Types (Preserve Safety)
If you want to keep the "safe cast" behavior (where invalid input results in null instead of a crash), you must cast to a Nullable value type (T?).
public void ProcessData(object input)
{
// ✅ Correct: Cast to 'int?' (Nullable int)
int? number = input as int?;
if (number != null) // or number.HasValue
{
System.Console.WriteLine($"Success: {number.Value}");
}
else
{
System.Console.WriteLine("Conversion failed (input was not an int).");
}
}
This is the closest equivalent to how as works with reference types.
Solution 2: Use Explicit Casting (Throw Exception)
If you are certain the object is an integer, or if you want the program to crash (throw an InvalidCastException) when the data is wrong, use the standard Explicit Cast.
public void ProcessData(object input)
{
try
{
// ✅ Correct syntax, but risky behavior
// This will throw an exception if 'input' is not an int.
int number = (int)input;
System.Console.WriteLine($"Number: {number}");
}
catch (InvalidCastException)
{
System.Console.WriteLine("Cast failed.");
}
catch (NullReferenceException)
{
System.Console.WriteLine("Input was null.");
}
}
Solution 3: Use Pattern Matching (Modern Approach)
In modern C# (versions 7.0+), the is operator with Pattern Matching is the preferred way to handle this. It combines the check, the cast, and the assignment into one safe, readable step.
public void ProcessData(object input)
{
// ✅ Recommended: 'is' checks the type and assigns variable 'i' if successful.
if (input is int i)
{
// 'i' is a standard 'int' here, not nullable.
System.Console.WriteLine($"Success: {i}");
}
else
{
System.Console.WriteLine("Input is not an integer.");
}
}
Pattern matching works for both Value Types (int) and Reference Types, making it a consistent coding style.
Conclusion
CS0077 protects you from logic errors where a failed cast would have nowhere to store its "failure" result.
- Understand
as: It returnsnullon failure. - Target Nullable Types: If you use
aswith a number, struct, or boolean, you must targetint?,struct?, orbool?. - Use Pattern Matching: Prefer
if (obj is int i)overasfor cleaner, safer code in modern C#.