Skip to main content

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:

  1. Reference conversions (e.g., Child class to Parent class).
  2. Boxing/Unboxing (e.g., int to object and back).
  3. Nullable conversions (e.g., int to int?).

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 if x is already a T (or inherits from it) in memory. If so, give me the reference; otherwise, give me null."

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;
}
note

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.

  1. Check the Operator: Are you using as?
  2. Check the Types: Do these types rely on a custom implicit/explicit operator to convert to each other? Or are they different primitive types (like double and int)?
  3. The Fix: If either is true, switch to the standard cast syntax (TargetType)variable to force the conversion logic to run. Only use as when preserving the existing reference (inheritance checks).