Tim
Tim

Reputation: 459

C# LINQ inner object query

I am too new to LINQ.

public static Dictionary<Type, ConfigurationObjectBase> MyDictionary;

This expression returns "Object reference not set to an instance of an object":

MyDictionary.First(o => o.Value.ID == 12).Key;

In fact, the object with ID = 12 is there.

Update:

In fact, the object with ID = 12 is there

it means, there is objects within dictionary where ID is 12.

Upvotes: 0

Views: 103

Answers (2)

Yeldar Kurmangaliyev
Yeldar Kurmangaliyev

Reputation: 34189

If there were no such item, then it would throw InvalidOperationException with message "Sequence contains no matching element".

It means that either:

  • your Dictionary is not initialized. You said that there is an object with ID = 12. So, it means that is it initialized.

  • there is at least one item in your dictionary where a value is null. So, while iterating, it tries to access its Value.ID and throws a NullReferenceException.

Imagine a simple loop over an array:

ConfigurationObjectBase Search()
{
    ConfigurationObjectBase[] array = { someObject1, someObject2, null, someObject3 };

    foreach (var item in array)
    {
        if (item.ID == 12) return item;
        // here, if item is null, you will try to access its ID and get NullReferenceException
    }

    throw new InvalidOperationException("Sequence contains no matching elements");
}

Actually, that's what LINQ exactly does. It iterates through the dictionary and once it tries to access a property of null, it throws an exception.

You may use the following code to avoid accessing the property of null:

MyDictionary.First(o => o.Value != null && o.Value.ID == 12).Key;

Upvotes: 3

Kamil Budziewski
Kamil Budziewski

Reputation: 23087

If there is an object with ID 12 it means that your dictionary contains objects which are null. You can filter for them:

MyDictionary.Where(x=>x.Value!=null).First(o => o.Value.ID == 12).Key;

It will skip all objects with null Value. I prefer chaining here, because it shows intention clearly.

EDIT: as @Yeldar Kurmangaliyev said this answer is good only for small dictionaries. If you want to go with big dictionaries better do:

MyDictionary.First(o => o.Value!=null && o.Value.ID == 12).Key;

Upvotes: 3

Related Questions