15

Here's my code:

        Event thisEvent = (from i in list
                           where (i.eventID == eventID)
                           select i).FirstOrDefault();
        if (thisEvent != null)
        {
            thisEvent.eventResolved = resolved;
            thisEvent.eventSequence.Add(item);
        }

"list" is a collection of IEnumerable, i.e.

IEnumerable<Event> list;

What I'm wondering is: after creating thisEvent using FirstOrDefault, is thisEvent still connected to list? In other words, when I change the two properties, eventResolved and eventSequence, is "list" actually changed, or is thisEvent just some totally disconnected copy of an item in "list"?

Cynthia
  • 2,100
  • 5
  • 34
  • 48

4 Answers4

23

FirstOrDefault selects an item in a collection, but does not "detatch" or "clone" it. I.e. it is the same instance. So if you modify a property you modify the original instance.

If you want to "detatch" the object you will have to copy it in some way or the other.

AxelEckenberger
  • 16,628
  • 3
  • 48
  • 70
2

list is not changed, and still includes the object returned by FirstOrDefault.

This is a general rule with all the LINQ operators: they never modify the source collection.

Also note that thisEvent is not a "copy" (unless Event is a value type (struct) rather than a class) -- it is a reference to the same object that is referenced in list.

itowlson
  • 73,686
  • 17
  • 161
  • 157
  • Hmmmm ... but if it's a reference to the same object, then the list would be changed, would it not? At least, in terms of that object -- not in terms of some element having been added or removed from the list. – Cynthia Mar 12 '10 at 22:57
  • The *list* is not changed. The same objects are still in the list after calling FirstOrDefault(). But yes, it it possible to modify a list *element* via the returned reference (again, assuming Event is a class rather than a struct). This is a characteristic of .NET references, not anything inherent to lists or FirstOrDefault: similarly, if you wrote `Event thatEvent = thisEvent;`, then changes made to the object through the `thatEvent` reference would also be seen through the `thisEvent` reference. One object, multiple references. – itowlson Mar 12 '10 at 23:04
  • It is hardly what happens in this case but for the sake of completeness take a look at this question (http://stackoverflow.com/questions/4052204/how-to-define-ienumerable-behavior-by-contract). It shows a possible scenario where FirstOrDefault() looks like disconnected (it was not. actually IEnumerable items were recreated when IEnumerable's source was a "yield return"). – AntonioR Nov 09 '10 at 21:48
1

Beware, this is true if your collection is in memory. If your collection is the result of a database query, the collection is not materialized until you call ToList on it. If you do FirstOrDefault before that, it will make a query to the database to return only this result and then materializing your collection will make a seperate call to the DB and you will not share the same instance. It just happened to me so I hope this can help someone else.

gbelzile
  • 84
  • 2
  • Yes, EF is designed as a Unit of Work per request when used in MVC. Once the request ends, the applicationDbContext will release the resources. If the result is preserved in a static variable, it will be different then the same object requested in a successive call. Some caching solutions might work, but I haven't found any to fit my needs. – profimedica Feb 27 '21 at 12:02
0

If Event is a reference type, then yes, modifying thisEvent will modify the element in the list.

Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928