0

I came across this answer that explains that it cannot be done, but I am wondering why.

Updating an item property within IEnumerable but the property doesn't stay set?

Take this code for example:

var MyClasses = new[] { 1, 2, 3, 4 }.Select(id => new MyClass { Id = id });

MyClass BobClass = MyClasses.FirstOrDefault(_mc => _mc.Id == 3);

BobClass.FirstName = "Bob";

Console.WriteLine("Id: {0}, FirstName: {1}", BobClass.Id, BobClass.FirstName);

foreach (var MyClass in MyClasses)
{
    Console.WriteLine("Id: {0}, FirstName: {1}", MyClass.Id, MyClass.FirstName);
}
  • I create a collection.
  • I get element with Id == 3 from the collection using FirstOrDefault(). This gets me a reference to the element within the collection.
  • I set its FirstName property to Bob
  • When I iterate through the list, FirstName is still null.

I don't understand how this works. I clearly get a reference to the original object, but it's almost as if FirstOrDefault() is giving me but a copy of the object rather than a reference. I can update the copy, but it obviously doesn't persist to the original because they're two entirely separate entities.

Update

Wow, this is interesting:

BobClass = MyClasses.FirstOrDefault(mc => object.ReferenceEquals(BobClass, mc));

Bob returns null...? Gotta say... I'm definitely stymied here.

Community
  • 1
  • 1
oscilatingcretin
  • 10,457
  • 39
  • 119
  • 206

1 Answers1

1

MyClasses is an IEnumerable. This will be executed every time you access it. This in itself does not make it impossible to update one of the classes. But... You create NEW instances of MyClass every time. These obviously will have uninitialized properties. If you add .ToList() you will get the behavior you expect.

Dabblernl
  • 15,831
  • 18
  • 96
  • 148
  • DUH... and they're not instantiated until the iterator gets started, so I am creating new objects every time I start using the iterator. Thanks. – oscilatingcretin Nov 07 '15 at 22:33
  • It makes sense when you start looking at lambdas as anonymous delegates. The `new MyClass()` expression exists in a delegate that has not yet been invoked, so it's going to execute `new MyClass()` on every iteration when the delegate is invoked. – oscilatingcretin Nov 07 '15 at 22:37