2013-12-16 16 views
11

Ho un elenco di oggetti che contengono un oggetto Persona che può avere un valore null. Quello che mi piacerebbe fare è ottenere il valore della proprietà Name del primo oggetto Person che non è null e se tutti gli oggetti Person sono nulli, restituisce una stringa vuota.LINQ - Valore di ritorno di una proprietà di un oggetto che non è nullo

mio miglior tentativo è la seguente:

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

Credo di capire il motivo per cui questo non funziona; se Person è nullo per ogni oggetto nel mio elenco, allora otteniamo il valore predefinito, che sarebbe nullo e genererà un errore di riferimento null quando provo ad accedere alla proprietà Person.

È possibile ottenere il risultato desiderato controllando se nessun oggetto non è nullo e quindi ottenere il primo, ma preferirei farlo in una istruzione LINQ. Qualsiasi input è apprezzato, grazie.

risposta

23

Il trucco solito sarebbe simile a questa:

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

o in seguito Servy's suggestion:

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

Aggiornamento ora è relativamente facile da fare questo con C# 6 di null-conditional operators:

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

+1 per la pulizia, singola query LINQ –

+2

Puoi usa anche "DefaultIfEmpty" per renderlo una soluzione puramente LINQ, se lo desideri. – Servy

+0

@Servy Buon punto. Ho incluso una soluzione DefaultIfEmpty che dovrebbe funzionare. –

0

Si accede a un oggetto nullo e si tenta di leggere le sue proprietà.

guardare in qualcosa di simile:

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

Buona fortuna!

2

Vorrei farlo con due prospetti:

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

È possibile controllare prima di avere persona non è nullo:

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

Questa era la mia soluzione iniziale, che funziona. La soluzione accettata raggiunge questo risultato in una singola query. Grazie per il tuo aiuto! – lobsterhat

Problemi correlati