Home > Software engineering >  Sum operation not giving expected results without appropriate bracket placement?
Sum operation not giving expected results without appropriate bracket placement?

Time:12-08

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));

CodePudding user response:

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
  • Related