2013-12-16 12 views
11

Mam listę obiektów, które zawierają obiekt Person, który może mieć wartość null. Chciałbym uzyskać wartość właściwości Name pierwszego obiektu Person, która nie jest pusta, a wszystkie obiekty Person są puste, zwracając pusty ciąg.LINQ - Zwracanie wartości właściwości obiektu, która nie jest pusta

Moja najlepsza próba jest następujący:

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

Chyba rozumiem, dlaczego to nie działa; Jeśli dla każdego obiektu na mojej liście Person ma wartość NULL, otrzymamy wartość domyślną, która będzie miała wartość NULL i spowoduje błąd zerowy odniesienia podczas próby uzyskania dostępu do właściwości Person.

Mogę uzyskać wynik, który chcę, sprawdzając, czy jakikolwiek obiekt nie jest pusty, a następnie otrzymuję pierwszy, ale wolałbym to osiągnąć w jednym poleceniu LINQ. Każde wejście jest doceniane, dzięki.

Odpowiedz

23

Zwykła sztuczka będzie wyglądać mniej więcej tak:

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

lub po Servy's suggestion:

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

Aktualizacja jest teraz stosunkowo łatwo zrobić z C# 6 na null-conditional operators:

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

+1 dla czystej, pojedynczej kwerendzie LINQ –

+2

Można również użyj 'DefaultIfEmpty', aby uczynić go czystym rozwiązaniem LINQ, jeśli chcesz. – Servy

+0

@Servy Dobry punkt. Zawarłem rozwiązanie DefaultIfEmpty, które powinno działać. –

0

Uzyskujesz dostęp do obiektu zerowego i próbujesz odczytać jego właściwości.

Spójrz na coś takiego:

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

Powodzenia!

2

Chciałbym to zrobić w dwóch sprawozdaniach:

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

Można sprawdzić najpierw, że nie masz zerowej osobę:

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

To było moje początkowe rozwiązanie, które działa. Przyjęte rozwiązanie spełnia to w jednym zapytaniu. Dziękujemy za pomoc! – lobsterhat

Powiązane problemy