How to Resolve Error "CS0039: Cannot convert type 'type1' to 'type2' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion" in C#
The Compiler Error CS0039 is a specific type conversion error that occurs primarily when using the as operator. The full message reads: "Cannot convert type 'TypeA' to 'TypeB' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion."
While the cast operator (Type) is powerful and can invoke custom conversion logic (like explicit operators) or numeric coercion, the as operator is strictly limited. It can only perform:
- Reference conversions (e.g., Child class to Parent class).
- Boxing/Unboxing (e.g.,
inttoobjectand back). - Nullable conversions (e.g.,
inttoint?).
If you try to use as to perform a conversion that requires a custom operator or a change in numeric representation (like double to int), the compiler raises CS0039.
Understanding the 'as' Operator Limits
The as operator is designed to be a "safe cast" that returns null instead of crashing if the cast fails. Because of this design, it ignores user-defined conversion logic.
- Cast
(T)x: Says "Convert this by any means necessary," including running custom methods you wrote to transform data. - Operator
x as T: Says "Check ifxis already aT(or inherits from it) in memory. If so, give me the reference; otherwise, give menull."
Scenario 1: Custom Implicit/Explicit Operators
This is the most common cause. You have defined a custom conversion between two classes (using implicit operator or explicit operator), but you try to trigger it using as.
Example of Mistake
You expect as to transform a Fahrenheit object into a Celsius object using your custom logic.
public class Fahrenheit
{
public double Degrees;
// We defined a custom way to convert this to Celsius
public static explicit operator Celsius(Fahrenheit f)
{
return new Celsius { Degrees = (f.Degrees - 32) * 5 / 9 };
}
}
public class Celsius
{
public double Degrees;
}
public class Program
{
static void Main()
{
Fahrenheit f = new Fahrenheit { Degrees = 100 };
// ⛔️ Error CS0039: Cannot convert type 'Fahrenheit' to 'Celsius' via a reference conversion...
// The 'as' operator ignores the 'explicit operator' method defined above.
// It looks at the memory and sees that 'f' is NOT a 'Celsius' object.
Celsius c = f as Celsius;
}
}
Solution: Use a Cast (Type)
Since you want to run a conversion method (creating a new object based on the old one), you must use the cast syntax.
public class Program
{
static void Main()
{
Fahrenheit f = new Fahrenheit { Degrees = 100 };
// ✅ Correct: This invokes the 'explicit operator Celsius' method
Celsius c = (Celsius)f;
System.Console.WriteLine(c.Degrees);
}
}
Scenario 2: Numeric Conversions
The as operator cannot be used to convert between numeric value types, even if they are nullable. It treats the types as fundamentally different data structures.
Example of Mistake
Trying to treat a double as a nullable int?.
public void ProcessNumbers()
{
double d = 10.5;
// ⛔️ Error CS0039: Cannot convert type 'double' to 'int?'
// Even though (int)d works, 'as' refuses to chop off the decimal.
int? i = d as int?;
}
Solution: Cast or Convert
Use a standard cast.
public void ProcessNumbers()
{
double d = 10.5;
// ✅ Correct: Explicit cast converts the number (truncating .5)
int? i = (int)d;
}
Type Checking with is:
If you aren't sure if the conversion is valid, you can use the is operator, which does support some unboxing conversions in newer C# versions, or simply stick to try-catch with casting if the types are uncertain.
Conclusion
CS0039 is the compiler telling you that you are using the wrong tool for the job.
- Check the Operator: Are you using
as? - Check the Types: Do these types rely on a custom
implicit/explicit operatorto convert to each other? Or are they different primitive types (likedoubleandint)? - The Fix: If either is true, switch to the standard cast syntax
(TargetType)variableto force the conversion logic to run. Only useaswhen preserving the existing reference (inheritance checks).