How to Resolve Error "CS0266: Cannot implicitly convert type 'type1' to 'type2'" in C#
The Compiler Error CS0266 is a type-safety error. The message reads: "Cannot implicitly convert type 'TypeA' to 'TypeB'. An explicit conversion exists (are you missing a cast?)".
This error occurs when you try to assign a value of one type to a variable of another type, but the conversion is not safe to do automatically. Usually, this means there is a risk of Data Loss (e.g., losing decimal precision) or an Invalid Cast exception at runtime (e.g., treating a generic Object as a specific String).
The compiler knows that a conversion is possible, but it refuses to do it unless you explicitly acknowledge the risk by using a Cast.
Understanding Implicit vs. Explicit Conversion
- Implicit Conversion: The compiler does it automatically because it is safe.
- Example:
int->double. An integer5fits perfectly into5.0. No data is lost.
- Example:
- Explicit Conversion: The compiler requires you to write
(Type)because it is risky.- Example:
double->int.5.9becomes5. Data is lost. - Example:
BaseClass->ChildClass. The object might not actually be that Child type.
- Example:
CS0266 is the compiler saying: "I can do this, but I won't do it unless you sign the waiver."
Scenario 1: Numeric Conversions (Loss of Precision)
This is the most common occurrence. You have a variable with high precision (like double or float) and you try to shove it into a variable with lower precision (like int).
Example of error
public void Calculate()
{
double price = 19.99;
// ⛔️ Error CS0266: Cannot implicitly convert type 'double' to 'int'.
// An explicit conversion exists (are you missing a cast?)
int displayPrice = price;
}
Solution: Add a Cast
If you accept that the decimal part will be truncated (chopped off), use the cast syntax (int).
public void Calculate()
{
double price = 19.99;
// ✅ Correct: The cast tells the compiler "I know I'm losing the .99"
int displayPrice = (int)price;
System.Console.WriteLine(displayPrice);
}
Output:
19
Casting effectively ignores the decimal. It does not round. If you need rounding, use Math.Round() or Convert.ToInt32() instead of a direct cast.
Scenario 2: Downcasting (Inheritance)
In Object-Oriented Programming, you often store specific objects in generic containers (e.g., storing a Dog in an Animal variable). This is Upcasting and is implicit.
However, if you have an Animal variable and you want to treat it as a Dog again, this is Downcasting. The compiler cannot guarantee that the Animal variable actually holds a Dog (it could be a Cat), so it raises CS0266.
Example of error
public class Animal { }
public class Dog : Animal { public void Bark() { } }
public class Program
{
static void Main()
{
// Upcast: Safe, Implicit
Animal myPet = new Dog();
// ⛔️ Error CS0266: Cannot implicitly convert type 'Animal' to 'Dog'.
// The compiler doesn't know for sure that 'myPet' is a Dog.
Dog myDog = myPet;
}
}
Solution: Cast or Pattern Match
You can force the cast if you are certain, or use safe pattern matching.
Option A: Explicit Cast (Risky)
Use this only if you are 100% sure. If myPet is actually a Cat, this throws an exception.
// ✅ Correct Syntax: Explicit cast
Dog myDog = (Dog)myPet;
myDog.Bark();
Option B: Pattern Matching (Safe - Recommended) Check the type and assign it in one step.
// ✅ Correct: Checks type safely
if (myPet is Dog safeDog)
{
safeDog.Bark();
}
Scenario 3: Interface to Concrete Types
This often happens when using LINQ or generic collections. IEnumerable<T> is an interface implemented by List<T>.
List<T>->IEnumerable<T>is Implicit.IEnumerable<T>->List<T>is Explicit (CS0266).
Example of error
using System.Collections.Generic;
using System.Linq;
public void ProcessList()
{
List<string> names = new List<string> { "Alice", "Bob" };
// .Where returns IEnumerable<string>
IEnumerable<string> query = names.Where(n => n.Length > 3);
// ⛔️ Error CS0266: Cannot implicitly convert 'IEnumerable<string>' to 'List<string>'.
List<string> filteredNames = query;
}
Solution: Use Conversion Methods
Do not use a direct cast (List<string>) here, because the LINQ result is often an iterator, not a real list. Use .ToList() or .ToArray().
using System.Collections.Generic;
using System.Linq;
public void ProcessList()
{
List<string> names = new List<string> { "Alice", "Bob" };
// ✅ Correct: Create a new List from the IEnumerable result
List<string> filteredNames = names.Where(n => n.Length > 3).ToList();
}
Conclusion
CS0266 is the compiler asking: "Are you sure?"
- Numeric Types: If converting larger types (
double) to smaller types (int), use(int)variable. Be aware of truncation. - Classes: If converting a Base Class to a Child Class, use
(ChildType)variableor the saferispattern matching. - Collections: If converting Interfaces (
IEnumerable) to Concrete types (List), use helper methods like.ToList().