I have a list of objects (using anonymous types) containing a decimal and an integer ID, and I'm building a function to take the sum of the decimals contained within all unique objects in the list.
This is the line of code I wrote:
var result = (objectList.Any()) ? objectList.Distinct().Sum(x => x.DecimalValue) : 0;
However, it always returns a decimal with the value 0, even though it should be returning the sum - objectList contains five identical objects in my example, so it should return the DecimalValue.
If I replace it with these two lines of code, however, it returns the DecimalValue:
decimal result = 0;
if (objectList.Any()) result = objectList.Distinct().Sum(x => x.DecimalValue);
Why does the second set of lines work, but the first line returns the wrong value? objectList.Any() is true, so it shouldn't be using the false assignment.
Update: I generated the list of anonymous types using this line of code:
var objectList = _ms.Read(cmd, x => new { DecimalValue = x.Field<decimal>("SomeColumnName"), Id = x.Field<int>("SomeColumnId") }).ToList();
_ms is a DAO for MS SQL, and it's running the lambda function that converts each datarow of the results to the anonymous typed object, which is returned in a list. I actually haven't been able to figure out how to build a list of those objects manually.
Another Update: Using Reed Copsey's reply below, I created the list manually in a way that duplicates the list that I'm getting, and I can reproduce the error with the manually created list:
var objectList = Enumerable.Range(0, 5).Select(i => new { DecimalValue = (decimal)31.45, Id = 3 }).ToList();
var result = (objectList.Any()) ? objectList.Distinct().Sum(x => x.DecimalValue) : 0;
I also tried removing the cast to decimal, and the issue is still present.
Another Update: After some further debugging I realized something I've never come across before. I set a breakpoint immediately after the line of code I mentioned that was having problems in each case. For the workaround, it returned 31.45. For the problem line, it returned 0. When I stepped into the next line, and looked at the variable again, it said 31.45. The line I set the breakpoint on did not access or modify the variable.
It would seem that both lines work, but that the debugger showed that it did not until I moved at least two lines after the code. I've never come across that before, but it shows that the code indeed does work.
There is no problem with your statement.
The issue is elsewhere, most likely in how you're constructing objectList.
For example, the following works exactly as expected, and prints "0.6" (as would be expected):
namespace Test
{
using System;
using System.Linq;
internal class TestCompile
{
private static void Main(string[] args)
{
var objectList = Enumerable.Range(0, 3).Select(i => new { ID = i, DecimalValue = i / 5.0m }).ToList();
decimal result = objectList.Any() ? objectList.Distinct().Sum(x => x.DecimalValue) : 0;
Console.WriteLine(result);
Console.ReadKey();
}
}
}
Update:
In response to your update, this also works perfectly:
private static void Main(string[] args)
{
var objectList = Enumerable.Range(0, 5).Select(i => new { DecimalValue = (decimal)31.45, Id = 3 }).ToList();
var result = (objectList.Any()) ? objectList.Distinct().Sum(x => x.DecimalValue) : 0;
Console.WriteLine(result);
Console.ReadKey();
}
It is using the exact code you pasted, and reports 31.45, as expected (due to the unique constraint). Note that, personally, I would use 31.45m instead of the cast, but it works even as written...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With