.net 如果没有适当的括号放置,求和运算不会给出预期结果?

a6b3iqyw  于 2022-12-14  发布在  .NET
关注(0)|答案(1)|浏览(77)

When I do a sum operation on some objects I have, they don't return the expected result and instead miss the last item in the list.
Here's the models used:

public class Item
{
    public decimal Price { get; set; }

    public List<ItemOption> Options { get; set; }
}

public class ItemOption
{
    public decimal? Price { get; set; }
}

So when I do a sum operation like so it gives incorrect results, missing the last item...

items.Sum(x => x.Price + x.Options?.Sum(c => c.Price) ?? 0);

But when I do it with brackets like this, it works...

Console.WriteLine(items.Sum(x => x.Price + (x.Options?.Sum(c => c.Price) ?? 0)));

Any idea why adding brackets here would make it work as expected?
Here's something I've tried, first write line returns £16.80 and 2nd write line returns £10.20

var items = new List<Item>
{
new Item
{
    Price = 4.20M,
    Options = new List<ItemOption>
    {
        new ItemOption
        {
            Price = null
        }
    }
},
new Item
{
    Price = 6.00M,
    Options = new List<ItemOption>
    {
        new ItemOption
        {
            Price = null
        }
    }
},
new Item
{
    Price = 1.30M
},
   new Item
{
    Price = 5.30M
}

};

Console.WriteLine(items.Sum(x => x.Price + (x.Options?.Sum(c => 
c.Price) ?? 0)));
Console.WriteLine(items.Sum(x => x.Price + x.Options?.Sum(c => 
c.Price) ?? 0));
thtygnil

thtygnil1#

This happens due to C# operator precedence, addition has higher precedence then null-coalescing operator, so in the first case if x.Options is null x.Price + x.Options?.Sum(c => c.Price) ?? 0 is evaluated as:

(x.Price + (decimal?)null) ?? 0

Which is evaluated as:

null ?? 0

Due to lifted operators rules:
The predefined unary and binary operators or any overloaded operators that are supported by a value type T are also supported by the corresponding nullable value type T? . These operators, also known as lifted operators, produce null if one or both operands are null; otherwise, the operator uses the contained values of its operands to calculate the result. For example:

int? a = 10;
int? b = null;
int? c = 10;

a++;        // a is 11
a = a * c;  // a is 110
a = a + b;  // a is null

相关问题