error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?)
means you stored a fractional (double) result in an int, which would lose the fraction. C#
will do it only if you say so with a cast, (int), and a cast cuts the fraction
off rather than rounding. Decide whether you want to truncate, round, or keep the
double.
Often the right fix is not a cast at all: if the value is money or a measurement, keep it
as a double (or a decimal for money) and round only when you
display it. Read the message as a question: the compiler is asking whether losing the
fraction is what you want, and the answer depends on what the number means in your
program, not on the syntax.
The error
...\Program.cs(3,13): error CS0266: Cannot implicitly convert type 'double' to 'int'. An explicit conversion exists (are you missing a cast?) [...\FixLab.csproj]
Build FAILED.
The folder part of both paths was shortened to ...; nothing else was changed.
Why it happens
double price = 19.99;
int quantity = 3;
int total = price * quantity;
Console.WriteLine($"Total: {total}");
Multiplying a double by an int gives a double
(59.97 here). Converting that to int can lose information, so C# allows it
only as an explicit conversion. That is what the message means by "an explicit conversion
exists": the conversion is possible, but you have to write the cast to show you accept the
loss. Going the other way, int to double, needs no cast because
nothing is lost.
The fix
double price = 19.99;
int quantity = 3;
int truncated = (int)(price * quantity);
int rounded = (int)Math.Round(price * quantity);
double exact = price * quantity;
Console.WriteLine($"Cast: {truncated}");
Console.WriteLine($"Rounded: {rounded}");
Console.WriteLine($"Kept as double: {exact}");
The three options printed different answers from the same numbers:
Cast: 59
Rounded: 60
Kept as double: 59.97
The plain cast dropped .97 and gave 59, which is the bug the compiler was warning you
about. Math.Round first and then the cast gave 60. For a price total, the
honest answer is the third: keep the fractional value. Note the brackets in
(int)(price * quantity): they make the cast apply to the product, not to
price alone.
How it was reproduced
A dotnet new console project on .NET SDK 10.0.403 (net10.0, nullable and
implicit usings on, no packages). dotnet build --no-incremental failed with the
CS0266 error; the fixed version passed
dotnet build --no-incremental -p:TreatWarningsAsErrors=true and
dotnet run printed the three lines above.
Frequently asked
- How do I convert a double to an int in C#?
- Write a cast, (int)value, which drops the fraction, or round first with (int)Math.Round(value). In the test, 59.97 became 59 with the plain cast and 60 with Math.Round. Note that Math.Round rounds halves to the even number: Math.Round(2.5) returned 2.
- Does casting a double to int round in C#?
- No. A cast truncates toward zero, so 59.97 becomes 59. Use Math.Round first to round, but check halves: Math.Round(2.5) returned 2 and Math.Round(3.5) returned 4, while Math.Round(2.5, MidpointRounding.AwayFromZero) returned 3.
- What does an explicit conversion exists mean?
- C# knows how to convert between the two types, but the conversion can lose data, so it will not do it silently. Writing the cast, such as (int), tells the compiler you accept that loss.
More decoded compiler errors are in the Fixes category.