64

Here is my code:

string displayName = Dictionary.FirstOrDefault(x => x.Value.ID == long.Parse(options.ID)).Value.DisplayName;

The code works fine if x.Value.ID matches options.ID. However, I get a NullReferenceException if it doesn't.

CarenRose
  • 1,266
  • 1
  • 12
  • 24
Raz Mahato
  • 875
  • 1
  • 7
  • 11

8 Answers8

108

FirstOrDefault returns the default value of a type if no item matches the predicate. For reference types that is null. Thats the reason for the exception.

So you just have to check for null first:

string displayName = null;
var keyValue = Dictionary
    .FirstOrDefault(x => x.Value.ID == long.Parse(options.ID));
if(keyValue  != null)
{
    displayName = keyValue.Value.DisplayName;
} 

But what is the key of the dictionary if you are searching in the values? A Dictionary<tKey,TValue> is used to find a value by the key. Maybe you should refactor it.

Another option is to provide a default value with DefaultIfEmpty:

string displayName = Dictionary
    .Where(kv => kv.Value.ID == long.Parse(options.ID))
    .Select(kv => kv.Value.DisplayName)   // not a problem even if no item matches
    .DefaultIfEmpty("--Option unknown--") // or no argument -> null
    .First();                             // cannot cause an exception
Tim Schmelter
  • 450,073
  • 74
  • 686
  • 939
  • 2
    The first solution didn't work. I am getting the same exception. The second one worked for me.Thank you. – Raz Mahato Jan 17 '14 at 04:42
  • 1
    I think that if it's a dictionary we can check if item key is null, not the item it self. The item will be the default item: var item = dict.FirstOrDefault(i => i.Key == something); if (!(item.Key == null)) – pnunes540 Dec 27 '17 at 11:15
20

You can use a combination of other LINQ methods to handle not matching condition:

var res = dictionary.Where(x => x.Value.ID == someID)
                    .Select(x => x.Value.DisplayName)
                    .DefaultIfEmpty("Unknown")
                    .First();
Konrad Kokosa
  • 16,563
  • 2
  • 36
  • 58
5

Simply use the question mark trick for null checks:

string displayName = Dictionary.FirstOrDefault(x => x.Value.ID == long.Parse(options.ID))?.Value.DisplayName ?? "DEFINE A DEFAULT DISPLAY NAME HERE";
sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40
3

That is because FirstOrDefaultcan return null causing your following .Value to cause the exception. You need to change it to something like:

var myThing = things.FirstOrDefault(t => t.Id == idToFind);

if(myThing == null)
    return; // we failed to find what we wanted
var displayName = myThing.DisplayName;
Zache
  • 1,023
  • 6
  • 14
  • 1
    I get the exception in the first line.So it didn't work.Thank u though. – Raz Mahato Jan 17 '14 at 04:48
  • 1
    Then your dictionary is probably null, or you have keys stored for a null value. You are also using a dictionary wrong, to retrieve values it's most common to use the index: [] Are you using the dictionary by choice? Perhaps you are deserializing JSON and it gives you a dictionary when you probably want a List instead? – Zache Jan 17 '14 at 07:53
3

To add to the solutions, here is a LINQ statement that might help

Utilities.DIMENSION_MemTbl.Where(a => a.DIMENSION_ID == format.ContentBrief.DimensionID).Select(a=>a.DIMENSION1).DefaultIfEmpty("").FirstOrDefault();

The result will be an empty string if the result of the query is a null..

pat capozzi
  • 1,412
  • 1
  • 20
  • 16
1

This answer is for those of us who need a visual write up (like me :)

In the code screenshot below, a NullReferenceException will be thrown, the root cause is the ReferenceIdentification_02 property.

enter image description here

When debugging, we see that the orderLine.REF array, I am querying does not include a matching object whose ReferenceIdentificationQualifier_01 value == "RU", so at that point FirstOrDefault() return value is NULL

enter image description here

to prevent the NullReferenceException, I do a FirstOrDefault() on the orderLine.REF array first. If the returned value is not null then I retrieve the value.

enter image description here

Geovani Martinez
  • 2,053
  • 2
  • 27
  • 32
0

i assume you are working with nullable datatypes, you can do something like this:

var t = things.Where(x => x!=null && x.Value.ID == long.Parse(options.ID)).FirstOrDefault();
var res = t == null ? "" : t.Value;
A.T.
  • 24,694
  • 8
  • 47
  • 65
-1

you can use with 'Where' statement with FirstOrDefault(). like this.

 var modelItem =  _dbcontext.ModelName.Where(n => n.NewsTagId == newsTag.Id).FirstOrDefault();

It returns first item if does not match query. It is better practice to check the NULL after query.

  if(modelItem == null)
  {
       return "Not Found."
  }
  else
  {
       // continue process
  }
MilanBogic
  • 162
  • 3
  • 9