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

时间:2011-11-30 20:57:30

标签: c# .net linq

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

这是我写的代码行:

var result = (objectList.Any()) ? objectList.Distinct().Sum(x => x.DecimalValue) : 0;

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

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

decimal result = 0;
if (objectList.Any()) result = objectList.Distinct().Sum(x => x.DecimalValue);

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

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

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

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

另一个更新:使用下面的Reed Copsey回复,我手动创建列表的方式与我获得的列表重复,我可以使用手动创建的列表重现错误:< / p>

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;

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

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

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

3 个答案:

答案 0 :(得分: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();
        }
    }
}

更新

为了回应您的更新,这也非常有效:

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

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

答案 1 :(得分:0)

为了它的价值,你的代码可以工作,虽然我必须自己构成类型。

[Test]
public void X()
{
    var objectList = Enumerable.Range(1, 10).Select(d => new {DecimalValue = Convert.ToDecimal(d)});

    var result = (objectList.Any()) ? objectList.Distinct().Sum(x => x.DecimalValue) : 0;

    Assert.AreEqual(55, result);
    Assert.AreEqual(typeof (decimal), result.GetType());
}

评论太大,所以CW就是。

答案 2 :(得分:0)

我刚刚编译了代码

    public class ObjectValue
    {
        public Decimal DecimalValue { get; set; }
    }

    class Program
    {

        static void Main(string[] args)
        {
            var objectList = new List<ObjectValue>() { new ObjectValue() { DecimalValue = 5 }, new ObjectValue() { DecimalValue = 5 } ,
                    new ObjectValue() { DecimalValue = 5 }};


            var result = (objectList.Any()) ? objectList.Distinct().Sum(x => x.DecimalValue) : 0;

            decimal resultDecimal = 0;
            if (objectList.Any())
                resultDecimal = objectList.Distinct().Sum(x => x.DecimalValue);

        }
    }

resultresultDecimal15,就我而言。正如我所料,我在两种情况下都得到了连贯的结果。所以错误就在其他地方。