tags:

views:

36

answers:

1

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.

+2  A: 

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();
spender
Thanks, I'll mark as answered in 8 minutes (SO won't let me sooner).I thought that each enumeration would only run once the first time it is referenced, and just be cached after that.Is there a way I can prevent the enumeration from running again on subsequent references?
TheEvilPenguin
Never mind, didn't see the edit :) Thanks, much appreciated
TheEvilPenguin
ToList() will not return an IOrderedEnumerable, I think.
Danny Chen
Fixed..........
spender