为什么我不能用三元运算符为小数分配值?

Jim*_*man 2 .net c# linq

我有一个包含小数和整数ID的对象列表(使用匿名类型),我正在构建一个函数来获取列表中所有唯一对象中包含的小数位的总和.

这是我写的代码行:

var result = (objectList.Any()) ? objectList.Distinct().Sum(x => x.DecimalValue) : 0;
Run Code Online (Sandbox Code Playgroud)

但是,它始终返回带有值的小数0,即使它应该返回sum - objectList在我的示例中包含五个相同的对象,因此它应该返回DecimalValue.

但是,如果我用这两行代码替换它,它将返回DecimalValue:

decimal result = 0;
if (objectList.Any()) result = objectList.Distinct().Sum(x => x.DecimalValue);
Run Code Online (Sandbox Code Playgroud)

为什么第二组行有效,但第一行返回错误的值?objectList.Any()是的,所以它不应该使用错误的赋值.

更新:我使用以下代码生成了匿名类型列表:

var objectList = _ms.Read(cmd, x => new { DecimalValue = x.Field<decimal>("SomeColumnName"), Id = x.Field<int>("SomeColumnId") }).ToList();
Run Code Online (Sandbox Code Playgroud)

_ms是MS SQL的DAO,它运行lambda函数,将结果的每个数据行转换为匿名类型对象,该对象在列表中返回.我实际上无法弄清楚如何手动构建这些对象的列表.

另一个更新:使用下面的Reed Copsey的回复,我手动创建列表的方式复制了我得到的列表,我可以用手动创建的列表重现错误:

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;
Run Code Online (Sandbox Code Playgroud)

我也尝试将强制转换为十进制,问题仍然存在.

另一个更新:经过一些进一步的调试后,我意识到我以前从未遇到的事情.我在提到的代码行之后立即设置了一个断点,在每种情况下都有问题.对于变通方法,它返回31.45.对于问题行,它返回0.当我走进下一行,再次查看变量时,它说31.45.我设置断点的行没有访问或修改变量.

看起来这两行都有效,但是调试器显示它直到我在代码之后至少移动了两行.我之前从未遇到过这种情况,但它表明代码确实有效.

Ree*_*sey 11

你的陈述没有问题.

问题出在其他地方,很可能就是你的建设方式objectList.

例如,以下工作完全按预期工作,并打印"0.6"(如预期的那样):

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:

为了响应您的更新,这也完美无缺:

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();
}
Run Code Online (Sandbox Code Playgroud)

它正在使用您粘贴的确切代码31.45,并按预期报告(由于唯一约束).请注意,就个人而言,我会使用31.45m而不是演员,但它的工作原理甚至可以写成...

  • @SaeedAmiri评论没有做到这一点.我做了一个完整的复制品,准确地显示了OP描述的内容,以及它是如何正常工作的.这远远超出了评论中可以包含的内容...... (3认同)
  • @SaeedAmiri这很好 - 这是IMO的一个非常有价值的答案,因为它证明了这个问题不是OP所怀疑的,而是代码中其他地方发生的其他事情. (2认同)
  • @SaeedAmiri:但显然OP没有. (2认同)