2011-11-30 104 views
2

我有一个包含小数和整数ID的对象列表(使用匿名类型),并且我构建了一个函数来获取列表中所有唯一对象中包含的小数的总和。为什么我不能使用三元运算符为小数赋值?

这是代码行我写道:

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

然而,它总是返回与价值0小数,即使它应该返回总和 - 链表类包含在我的例子中五个相同的对象,所以它应该返回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函数匿名类型对象,它在列表中返回。我实际上一直无法弄清楚如何手动建立这些对象的列表。

另一个更新:使用下面里德•科普塞的答复,我在重复那我得到的名单的方式手动创建的列表,我可以重现该错误与手动创建的列表:

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。我设置断点的那一行没有访问或修改变量。

似乎两行都能正常工作,但是调试器显示它没有在代码之后移动至少两行。我从来没有遇到过,但它表明,代码确实工作。

+0

我没有看到你的第一条语句有什么问题 - 结果应该是一样的 – BrokenGlass

+3

在赋值之后'var result'的类型是什么?是否有可能C#从三元表达式中推断出不正确的类型(比如'int')? – climbage

+2

'objectList'包含什么?如果你将它定义为'var objectList = new List {5,5,5,5};'由于你的三元表达式(显然删除了'DecimalValue'),我得到'5',所以它必须是与该类型有关。我们需要查看列表包含的内容。 –

回答

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而不是演员,但它仍然可以正常工作......

+0

-1,并不是宝贵的答案,因为赞扬说,像我的downvote的问题。 –

+2

@SaeedAmiri这很好 - 它是IMO的一个非常有价值的答案,因为它证明问题不是OP所怀疑的问题,而是他的代码中其他地方发生的其他事情。 –

+1

这是你的想法,可能是upvoters,但IMO 50%的人对问题发表评论或评论错误的答案知道这不是问题。 –

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它是。

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,在我的情况。正如我预料的那样,我在两个案例中都有一致的结果。所以错误在别的地方。

相关问题