TheEvilPenguin
TheEvilPenguin

Reputation: 5682

Setting property while enumerating over IOrderedEnumerable<> doesn't set property on object in collection

I'm at a bit of a loss here. I'm creating a collection of objects from another collection using LINQs .Select and then using .OrderBy to get an IOrderedEnumerable. This part works fine, but when I loop over this with foreach and set a property on the object in the collection, the object in the collection is not modified.

I'm writing and running in VS2008/.NET 3.5 SP1.

Here's some sample code that reproduces the issue (written and tested in LINQPad, but it's behaving the same as in 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; }
}

I'd really appreciate any hints about what I'm doing wrong here.

Upvotes: 1

Views: 1272

Answers (1)

spender
spender

Reputation: 120498

You're running the enumeration twice, once with the first foreach, but again with trueObjs.Count(). Given that enumeration invokes new MyClass(n), you're ending up with a fresh set of objects second time round.

Quick fix: change first line to:

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

Upvotes: 2

Related Questions