Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Sum operation not giving expected results without appropriate bracket placement?

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…

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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

>Solution :

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
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading