Home > database >  C# grouped objects aren't being mutated as expected
C# grouped objects aren't being mutated as expected

Time:12-24

I have a collection of objects entering a method as an IEnumerable of which I am grouping them by a reference property and then processing them group by group. The processing involves mutating the other properties of the objects. When the method completes and returns, the caller expects to have the collection of objects it passed in to be mutated. The whole process is asynchronous and the method looks like the following:

public async Task MutateMyObjects(IEnumerable<MyObjects> myObjects,
    CancellationToken cancellationToken)
{
    var myObjectsGroupedByGroupingEntity = myObjects
        .GroupBy(myObject => myObject.GroupingEntity);

    foreach (var myObjectGroup in myObjectsGroupedByGroupingEntity )
    {
        await ProcessGroup(myObjectGroup.Key, myObjectGroup, cancellationToken);
    }
}

Both MyObject and GroupingEntity are classes, as such my expectation is that MyObjects are passed as reference types and mutation is inherent through the process.

What actually happens is the caller of MutateMyObjects observes the same property values of MyObjects as it observed before the method call. These results are observed after the Task completes. While debugging the method above, observing the variable states before the method returns shows that the object collection under the variable myObjectGroup contain the mutated properties while the object collection under the variable myObjects does not.

I'm not sure what aspect of my understanding is missing causing me to get the wrong expectation, any insights would be greatly appreciated.

CodePudding user response:

The issue is that I needed to execute the LINQ query first to materialise the objects before sending them off for mutation. What isn't shown in the question is how the IEnumerable<MyObject> myObjects is represented. In my case, myObjects was a deferred execution of a database fetch piped into an object mapping. This meant that when I mutated the objects, the groupBy forced the initialisation of the objects which were subsequently lost when the shown method returned. When the "mutated" objects were "used", the objects were in fact reinitialised.

As pointed out by @Enigmativity, in this method, the signature should probably be asking for IList<MyObject> to be sure of the existence of the objects as the method intends to mutate them. This means that the caller of the method is required to execute any LINQ queries before calling the method thereby avoiding this pitfall.

  • Related