LINQ - возвращаемое значение свойства объекта, который не является нулевым

У меня есть список объектов, которые содержат объект Person, который может иметь нуль. То, что я хотел бы сделать, это получить значение свойства Name объекта First Person, которое не является нулевым, и если все объекты Person равны null, верните пустую строку.

Моя лучшая попытка заключается в следующем:

    string userName = MyObjectList.FirstOrDefault(x => x.Person != null).Person.Name ?? string.Empty;

Думаю, я понимаю, почему это не работает; если лицо является нулевым для каждого объекта в моем списке, то мы получим значение по умолчанию, которое будет нулевым и отбросит нулевую ссылочное сообщение об ошибке при попытке получить доступ к собственности Person.

Я могу получить результат, который я хочу, проверив, если какой-либо объект не является нулевым, а затем первым, но я предпочел бы выполнить это в одном операторе LINQ. Любой вход оценивается, спасибо.

Ответ 1

Обычный трюк будет выглядеть примерно так:

string userName = MyObjectList.Where(x => x.Person != null)
                              .Select(x => x.Person.Name)
                              .FirstOrDefault() ?? string.Empty;

Или следуя Рекомендация сервера:

string userName = MyObjectList.Where(x => x.Person != null)
                              .Select(x => x.Person.Name)
                              .DefaultIfEmpty(string.Empty)
                              .First();

Обновить теперь относительно легко сделать это с помощью С# 6 операторов с нулевым условием:

string userName = MyObjectList.FirstOrDefault(x => x.Person != null)?.Person.Name ?? string.Empty;

Ответ 2

Я бы сделал это как два утверждения:

var personContainer = MyObjectList.FirstOrDefault(x => x.Person != null);
string userName = personContainer == null ? string.Empty : personContainer.Person.Name;

Ответ 3

Вы получаете доступ к нулевому объекту и пытаетесь прочитать его свойства.

Посмотрите на что-то вроде этого:

var obj = MyObjectList.FirstOrDefault(x => x.Person != null);
string userName = string.Empty;
if (null != obj) {
    userName = obj.Person.Name;
}

Удачи!

Ответ 4

Сначала вы можете проверить, что у вас нет null Person:

string userName = (MyObjectList.Any((x => x.Person != null))) ? MyObjectList.FirstOrDefault(x => x.Person != null).Person.Name : stringEmpty;