Skip to main content

Fixed: "error CS0266: Cannot implicitly convert type 'decimal?' to 'decimal'" in C# (Nullable Decimal)

· 4 min read
Jagdish Kumawat
Founder @ Dewiride

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:

The two properties
// CreateProductRequest (the request)
[Required, Money] decimal? UnitPrice,

// Product (the entity)
public decimal UnitPrice { get; set; }

I copied one to the other:

src/Dewiride.Inventory.Api/Features/Products/ProductEndpoints.cs (excerpt)
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​

Output (the path is shortened)
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.

A terminal where dotnet build fails with error CS0266: Cannot implicitly convert type 'decimal?' to 'decimal', and CS8629: Nullable value type may be null, on the same line.

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:

src/Dewiride.Inventory.Api/Features/Products/ProductEndpoints.cs (excerpt)
UnitPrice = request.UnitPrice.GetValueOrDefault(),

This API's validation has already refused a missing price, so GetValueOrDefault() always finds one here. Other options:

CodeWhen there's no valueUse it when
request.UnitPrice.GetValueOrDefault()0null is already ruled out
request.UnitPrice ?? 9.99mThe default you giveThere's a sensible default
(decimal)request.UnitPrice!Throwsnull would be a bug you want to see

After the Fix​

Output
Build succeeded.
0 Warning(s)
0 Error(s)

A terminal where dotnet build succeeds with no warnings and no errors.

Common Mistakes​

MistakeWhat happensDo this instead
Adding the cast the message suggests, without thinkingIt throws at runtime on nullDecide what null should do
Making the entity's property decimal? tooThe column allows NULL, so every reader has to handle itConvert at the edge
Making the request's property plain decimalA missing price silently becomes 0Keep decimal? with [Required]

Troubleshooting​

SymptomLikely causeFix
CS0266 for decimal? to decimalAssigning a nullable to a plain valueUse GetValueOrDefault() or ??
The same for int? to int, or DateTime? to DateTimeThe same ruleThe same
CS8629: Nullable value type may be null aloneYou used .ValueSee that post
InvalidOperationException: Nullable object must have a valueA cast or .Value on null at runtimeValidate 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​

Stay Updated

Subscribe to our newsletter for the latest tutorials, tech insights, and developer news.

By subscribing, you agree to our privacy policy. Unsubscribe at any time.