How to Resolve Error "CS0030: Cannot convert type 'type' to 'type'" in C#
The Compiler Error CS0030 is an Explicit Conversion error. The message reads: "Cannot convert type 'TypeA' to 'TypeB'".
This error occurs when you attempt to cast a variable from one type to another using the explicit cast syntax (Type), but the compiler cannot find a way to perform that conversion. Unlike CS0029 (which happens during implicit assignment), CS0030 means that even though you explicitly asked for the conversion, the compiler sees no relationship (inheritance) and no user-defined logic (operators) to make it happen.
This guide explains how to define these relationships or use intermediate techniques to resolve the error.
Understanding Explicit Conversion
In C#, a cast like (int)myObject is not a magic command that forces memory to change shape. It instructs the compiler to look for one of two things:
- Inheritance Relationship: Is the object actually a child or parent of the target type?
- Conversion Operator: Did the developer write a specific method (
explicit operator) telling the code how to transform Type A into Type B?
If neither exists, the compiler throws CS0030.
Scenario 1: Converting Unrelated Custom Types
This is the most straightforward cause. You have two classes that look similar (perhaps they have the same properties), but they do not inherit from each other.
Example of Mistake
public class Fahrenheit
{
public double Degrees { get; set; }
}
public class Celsius
{
public double Degrees { get; set; }
}
public class Program
{
static void Main()
{
Fahrenheit f = new Fahrenheit { Degrees = 100 };
// ⛔️ Error CS0030: Cannot convert type 'Fahrenheit' to 'Celsius'
// Even though they look similar, the compiler doesn't know how to translate them.
Celsius c = (Celsius)f;
}
}
Solution: Define an Explicit Operator
You can teach the compiler how to convert these types by adding an operator method inside one of the classes.
public class Fahrenheit
{
public double Degrees { get; set; }
}
public class Celsius
{
public double Degrees { get; set; }
// ✅ Correct: Define how to convert Fahrenheit TO Celsius
public static explicit operator Celsius(Fahrenheit f)
{
return new Celsius { Degrees = (f.Degrees - 32) * 5 / 9 };
}
}
public class Program
{
static void Main()
{
Fahrenheit f = new Fahrenheit { Degrees = 100 };
// ✅ Correct: The cast now triggers the method defined above
Celsius c = (Celsius)f;
System.Console.WriteLine($"C: {c.Degrees}");
}
}
Scenario 2: Generic Type Casting
When working with Generics (T), the compiler treats T as a "Black Box." It doesn't know if T will be an int, a string, or a List. Therefore, it forbids direct casting from T to a specific type, because that cast would be invalid for most other types.
Example of Mistake
public class Converter<T>
{
public int ConvertToInt(T value)
{
// ⛔️ Error CS0030: Cannot convert type 'T' to 'int'
// If T turns out to be a 'string', this cast is impossible.
return (int)value;
}
}
Solution: Double Casting (Boxing) or Pattern Matching
You can trick the compiler by casting to object first (which works for everything), and then to the target type. Alternatively, use the as operator or pattern matching.
public class Converter<T>
{
public int ConvertToInt(T value)
{
// ✅ Correct: Cast to object first (Boxing), then to int (Unboxing)
// This shifts the check from Compile-Time to Runtime.
return (int)(object)value;
}
}
Using (int)(object)value will compile, but it will throw an InvalidCastException at runtime if T is not actually an integer.
Scenario 3: LINQ and Interface Confusion
CS0030 often appears in LINQ queries when you try to cast a collection of one type to a completely different collection type using standard casting syntax.
Example of Mistake
Trying to cast a List<double> to a List<int> directly.
using System.Collections.Generic;
public class Data
{
public void Process()
{
List<double> scores = new List<double> { 10.5, 20.2 };
// ⛔️ Error CS0030: Cannot convert type 'List<double>' to 'List<int>'
// Generic collections cannot be cast to each other, even if the contents could be.
List<int> intScores = (List<int>)scores;
}
}
Solution: Use Projection (Select)
You must convert the items inside the list, not the list itself.
using System.Collections.Generic;
using System.Linq;
public class Data
{
public void Process()
{
List<double> scores = new List<double> { 10.5, 20.2 };
// ✅ Correct: Convert each item individually, then make a new list
List<int> intScores = scores.Select(s => (int)s).ToList();
}
}
Conclusion
CS0030 means you tried to force a conversion that the compiler deems impossible based on the definitions it sees.
- Check Relationships: Does the object inherit from the target type? If not, casting won't work automatically.
- Check Operators: If they are custom classes, have you written an
explicit operator? - Check Generics: If casting
T, cast toobjectfirst (the "universal donor") before casting to the specific type. - Check Collections: Never cast
List<A>toList<B>. Convert the elements using LINQ instead.