Fixed: "error CS0266: Cannot implicitly convert type 'decimal?' to 'decimal'" in C# (Nullable Decimal)
error CS0266: Cannot implicitly convert type 'decimal?' to 'decimal'. An explicit conversion exists (are you missing a cast?) A nullable value can be empty, and a plain decimal can't hold "empty", so C# won't copy one to the other without being told how. The cast the message suggests compiles, but it throws at runtime if the value is null, so choose what should happen in that case.
What I Was Doing
In a .NET 10 Web API, the request has a nullable price, and the EF Core entity has a plain one:
// CreateProductRequest (the request)
[Required, Money] decimal? UnitPrice,
// Product (the entity)
public decimal UnitPrice { get; set; }
I copied one to the other:
var product = new Product
{
// …
UnitPrice = request.UnitPrice,
// …
};
What I Expected
Build succeeded. It's the same kind of number on both sides.
What I Got
ProductEndpoints.cs(41,25): error CS0266: Cannot implicitly convert type 'decimal?' to 'decimal'. An explicit conversion exists (are you missing a cast?)
ProductEndpoints.cs(41,25): error CS8629: Nullable value type may be null.

What I Checked
What decimal? is. C#'s nullable value types page explains it: decimal? is short for Nullable<decimal>, a different type from decimal, which can also hold null. Going from decimal to decimal? always works, so that direction is automatic. The other direction can fail, so it needs saying.
What the suggested cast does. (decimal)request.UnitPrice compiles, and the page says that when the value is null, the cast throws at runtime. So it swaps a compile error for a possible InvalidOperationException.
Why It Happens
C# only converts automatically when nothing can go wrong. A decimal? may have no value, and a decimal has no way to represent that, so the compiler asks you to decide. The second error on the same line, CS8629, is the nullable analysis saying the same thing.
The Fix
Say what happens when there's no value:
UnitPrice = request.UnitPrice.GetValueOrDefault(),
This API's validation has already refused a missing price, so GetValueOrDefault() always finds one here. Other options:
| Code | When there's no value | Use it when |
|---|---|---|
request.UnitPrice.GetValueOrDefault() | 0 | null is already ruled out |
request.UnitPrice ?? 9.99m | The default you give | There's a sensible default |
(decimal)request.UnitPrice! | Throws | null would be a bug you want to see |
After the Fix
Build succeeded.
0 Warning(s)
0 Error(s)

Common Mistakes
| Mistake | What happens | Do this instead |
|---|---|---|
| Adding the cast the message suggests, without thinking | It throws at runtime on null | Decide what null should do |
Making the entity's property decimal? too | The column allows NULL, so every reader has to handle it | Convert at the edge |
Making the request's property plain decimal | A missing price silently becomes 0 | Keep decimal? with [Required] |
Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
CS0266 for decimal? to decimal | Assigning a nullable to a plain value | Use GetValueOrDefault() or ?? |
The same for int? to int, or DateTime? to DateTime | The same rule | The same |
CS8629: Nullable value type may be null alone | You used .Value | See that post |
InvalidOperationException: Nullable object must have a value | A cast or .Value on null at runtime | Validate first, or use ?? |
FAQ
Why is it allowed the other way around?
Every decimal fits in a decimal?, so nothing can go wrong, and C# converts it for you.
Does this apply to reference types?
No. A string? and a string are the same type at runtime. There you get a nullable warning, such as CS8601, not this error.
Conclusion
error CS0266: Cannot implicitly convert type 'decimal?' to 'decimal' is C# asking what should happen if the value is null. Use GetValueOrDefault() when validation has ruled it out, ?? when there's a sensible default, and a cast only when null would be a bug you want to see.
Additional Resources
- Nullable value types — conversions,
??andGetValueOrDefault.
