2012-03-30 2 views
17

Sono nuovo di LINQ. Ho bisogno di calcolare new_id come segue:LINQ "MaxOrDefault"?

public class C_Movement 
{ 
    public int id=-1; 
    public static ObservableCollection<C_Movement> list=new ObservableCollection<C_Movement>(); 
    // ... 
} 

int new_id = (C_Movement.list.Count==0) ? 0 : C_Movement.list.Max(x => x.id)+1; 

Esiste un modo per compattare LINQ quell'espressione, in modo che io non devo usare il ":" struttura? Il problema è che, quando C_Movement.list non contiene elementi, C_Movement.list.Max (x => x.id) restituisce null (e mi piacerebbe che restituisse -1, invece).

Grazie.

metodo
+2

Come può restituire null quando restituisce un intero? – MikeP

+1

Per riferimento futuro, la struttura "?:" Viene in realtà chiamata * l'operatore condizionale * (nei documenti MSDN), ma la maggior parte della gente lo chiama * l'operatore ternario. * :) –

risposta

39

DefaultIfEmpty dovrebbe aiutare:

int new_id = C_Movement.list.Select(x => x.id).DefaultIfEmpty(-1).Max()+1; 
+2

In inglese: [DefaultIfEmpty] (http: // msdn.microsoft.com/en-us/library/bb355419.aspx) – Steve

+2

@Steve, grazie. L'ho modificato, non esitare a cambiarlo la prossima volta. – Snowbear

2

ne dite:

int new_id = 0; 

if (C_Movement.list.Any()) 
    new_id = C_Movement.list.Max(x => x.id) + 1; 
+2

non hai bisogno di un 'else' qui dato che lo hai già impostato a' 0' – hunter

+0

È vero, credo di essere anale per certe cose. Le cattive abitudini sono dure a morire! –

+0

Il problema principale con questa versione è che raddoppierà l'iteratore. Il "Qualsiasi" sarà la prima iterazione e il "Max" sarà il secondo. Questa implementazione dovrebbe essere evitata. – srm

3

int new_id = C_Movement.list.Max(x => (int?)x.id).GetValueOrDefault(-1) + 1;

dove GetValueOrDefault è un method di Nullable<T>.

+3

Vale la pena notare che solo Max() sulle raccolte di tipi nullable restituisce null per la sequenza vuota mentre Max() in generale genera un'eccezione. – sluki