0

I have a collection of objects that I am trying to query with LINQ. Inexplicably, the code is crashing when querying for a specific value.

SomeObject[] myObjects = { ... };

foreach (int id in someIDs)
{
    SomeObject singleObject = myObjects.FirstOrDefault(x => x.ID = id);
}

This code is failing when the value of id is a specific value. The error I get is that x is NULL. The myObjects array is not NULL, and does contain an object with an ID value that matches the value of id that is failing. Other values of id do not cause the error. When id is the value that is failing, I can step through the LINQ expression as it iterates through the items in the array. The parameter x has a value for every item in the collection up until it reaches the item before the item that matches the problematic value of id; at that point x suddenly becomes NULL and an exception is thrown.

How could the input parameter of a LINQ expression on a non-NULL collection ever be NULL? Even if the collection did not contain an item with ID matching id, it should just return the default value for my object type, not crash with a NULL error.

5
  • 4
    It isn't saying that myObjects is null, it's saying that an element member of myObjects is null. E.g. SomeObject[] myObjects = new[] { foo, bar, null, baz };. Commented Oct 14, 2020 at 16:15
  • 2
    x => x != null && x.ID = id Commented Oct 14, 2020 at 16:15
  • Also, your posted code has poor runtime complexity (O( n * m )). You should convert myObjects to a dictionary first (outside of the loop) so you get O(1) lookup inside the loop and O( n ) overall performance. Commented Oct 14, 2020 at 16:17
  • 1
    myObjects.FirstOrDefault(x => x?.ID == id); Commented Oct 14, 2020 at 16:19
  • @Dai, thanks. I was getting confused because the collection shouldn't have contained any nulls. Turns out a bug further up the line had been inserting nulls into the collection. Commented Oct 14, 2020 at 19:11

1 Answer 1

1

Fix the nulls and improve runtime performance drastically like so:

SomeObject[] myObjects = new[] { ... };

Dictionary<Int32,SomeObject> dict = myObjects
    .Where( mo => mo != null )
    .ToDictionary( mo => mo.id );

foreach( Int32 id in someIds )
{
    if( dict.TryGetValue( id, out SomeObject singleObject ) )
    {
        // do stuff here
    }
    else
    {
        // don't do stuff here
    }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.