【问题标题】:Setting property while enumerating over IOrderedEnumerable<> doesn't set property on object in collection在枚举 IOrderedEnumerable<> 时设置属性不会在集合中的对象上设置属性
【发布时间】:2010-06-29 10:45:25
【问题描述】:

我在这里有点茫然。我正在使用 LINQ .Select 从另一个集合创建对象集合,然后使用 .OrderBy 获取 IOrderedEnumerable。这部分工作正常,但是当我使用 foreach 循环并在集合中的对象上设置属性时,集合中的对象不会被修改。

我在 VS2008/.NET 3.5 SP1 中编写和运行。

这里有一些重现问题的示例代码(在 LINQPad 中编写和测试,但它的行为与 VS 中相同):

void Main()
{
    IOrderedEnumerable<MyClass> objects = Enumerable.Range(0, 10)
            .Select(n => new MyClass(n))
            .OrderBy(o => o.ObjectNumber);

    foreach (MyClass obj in objects)
    {
        obj.MyProperty = true;
    }

    var trueObjs = objects.Where(o => o.MyProperty);

    if (trueObjs.Count() == 0)
    {
        Debug.WriteLine("No object in 'objects' has MyProperty == true");
    }
    else
    {
        Debug.WriteLine("Found");
    }
}

public class MyClass
{
    public MyClass(int objectNumber)
    {
        ObjectNumber = objectNumber;
        MyProperty = false;
    }

    public int ObjectNumber { get; private set; }
    public bool MyProperty { get; set; }
}

我真的很感激任何关于我在这里做错的提示。

【问题讨论】:

    标签: c# linq


    【解决方案1】:

    您运行了两次枚举,一次使用第一个foreach,但再次使用trueObjs.Count()。鉴于枚举调用new MyClass(n),您将在第二轮中得到一组新的对象。

    快速修复:将第一行更改为:

    var objects = Enumerable.Range(0, 10)
            .Select(n => new MyClass(n))
            .OrderBy(o => o.ObjectNumber)
            .ToList();
    

    【讨论】:

    • 谢谢,我会在 8 分钟后将其标记为已回答(所以不会再让我这样做了)。我认为每个枚举只会在第一次被引用时运行一次,然后才被缓存。有没有办法阻止枚举在后续引用中再次运行?
    • 我认为 ToList() 不会返回 IOrderedEnumerable。
    猜你喜欢
    • 2014-02-28
    • 1970-01-01
    • 2010-09-23
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多