FirstOrDefault возвращает исключение NullReferenceException, если совпадение не найдено

вот мой код

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

Код работает нормально, если x.Value.ID соответствует options.ID. Однако я получаю исключение nullreference, если это не так.

Ответы

Ответ 1

FirstOrDefault возвращает значение по умолчанию для типа, если ни один элемент не соответствует предикату. Для ссылочных типов null. Это причина исключения.

Итак, вам просто нужно сначала проверить null:

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

Но каков ключ словаря, если вы ищете в значениях? A Dictionary<tKey,TValue> используется для нахождения значения с помощью ключа. Может быть, вам следует реорганизовать его.

Другим вариантом является предоставление значения по умолчанию с помощью 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

Ответ 2

Вы можете использовать комбинацию других методов LINQ для обработки несоответствующего условия:

var res = dictionary.Where(x => x.Value.ID == someID)
                    .Select(x => x.Value.DisplayName)
                    .DefaultIfEmpty("Unknown")
                    .First();

Ответ 3

Это потому, что FirstOrDefault может возвращать null, вызывая следующее .Value, чтобы вызвать исключение. Вам нужно изменить его на что-то вроде:

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

if(myThing == null)
    return; // we failed to find what we wanted
var displayName = myThing.DisplayName;

Ответ 4

Я предполагаю, что вы работаете с нулевыми типами данных, вы можете сделать что-то вроде этого:

var t = things.Where(x => x!=null && x.Value.ID == long.Parse(options.ID)).FirstOrDefault();
var res = t == null ? "" : t.Value;

Ответ 5

Чтобы добавить к решениям, вот оператор LINQ, который может помочь

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

Результат будет пустой строкой, если результатом запроса является нуль.