Linq中的问题对象where子句:条件被绕过

时间:2013-03-08 16:32:09

标签: c# linq where

大家好,

今天,这是我在我最喜欢的C#帮助资源网站上发表的第一篇文章。我很想加入社区。

这是我的问题,我想调用。选择linq子句在使用.Where子句过滤双值列表后创建结构列表,但过滤条件似乎没有被评估或者它们返回总是如此 请查看我的代码以便更好地理解该问题:

string[] msgNames = new string[] { "de", "vf", "ze", "ki", "vt", "er" };
double[] prevCounters = new double[] { 154.0, 24588.0, 4547.0, 788.0, 1455.0, 24577.0 };
double[] counters = new double[] { 8548.0, 54854.0, 54854.0, 44.0, 121.0, 48547.0 };
double[] lenValues = new double[] { 1.0, 2.0, 0.0, 4.0, 5.0, 0.0 };

BufferInfo[] positiveLenValues = counters
    .Where((c, it) => lenValues[it] >= 1.0 && prevCounters[it] != c)
    .Select((c, it) =>
    {
        prevCounters[it] = c;

        return new BufferInfo()
        {
            Name = msgNames[it],
            Length = lenValues[it]
        };
    }).ToArray();

也许我误解了linq的用法,但最后返回的BufferInfo []包含所有值,而lenValues数组中的某些值小于1.0。有关信息,没有对此代码块的并发访问权限.linq bloc上的局部变量通常是动态实例化的(由NI的外部程序集重新调整),这只是为了让您知道。

例如,同样的bahaviour但带有for循环也可以:

List<BufferInfo> myInfos = new List<BufferInfo>();

for (int i = 0; i < 6; i++)
{
    if (lenValues[i] >= 1.0 && prevCounters[i] != counters[i])
    {
        oldCounters[i] = counters[i];
        myInfos.Add(new BufferInfo()
                    {
                        Length = lenValues[i],
                        Name = msgNames[i]
                    });
    }
}

BufferInfo[] buffers = myInfos.ToArray();

我不在乎使用linq,我只是想了解它失败的原因 请解释一下我为什么会得到这些奇怪的结果。

最好的问候,
纶@ IR。

2 个答案:

答案 0 :(得分:2)

嗯,那是因为你的.Select((c, it) =>再次从0开始索引......

因此,如果您的Where子句过滤项目并仅返回4个项目,则Select将使用索引0, 1, 2, 3,这与您返回的项目的索引不对应Where {{1}} 1}}。

答案 1 :(得分:1)

你的代码甚至没有编译,所以我不知道你是如何测试它是不行的......

您必须首先编写Select来获取索引,然后将其传递给Where方法:

BufferInfo[] positiveLenValues = counters.Select((c, i) => new { c, i })
                                         .Where(e => lenValues[e.i] >= 1.0 && prevCounters[e.i] != e.c)
                                         .Select(e =>
                                         {
                                             prevCounters[e.i] = e.c;
                                             return new BufferInfo
                                             {
                                                 Name = msgNames[e.i],
                                                 Length = lenValues[e.i]
                                             };
                                         }).ToArray();

该代码返回4个值,可预测的并且似乎是正确的结果。