2012-03-30 12 views
17

Soy nuevo en LINQ. Necesito calcular NEW_ID de la siguiente manera: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; 

¿Hay una manera de LINQ para compactar esa expresión, por lo que yo no tengo que usar el ":" estructura? El problema es que, cuando C_Movement.list no contiene elementos, C_Movement.list.Max (x => x.id) devuelve null (y me gustaría que devuelva -1, en su lugar).

Gracias.

método
+2

¿Cómo puede devolver nulo cuando devuelve un número entero? – MikeP

+1

Para referencia futura, la estructura "?:" Se llama realmente * el operador condicional * (en documentos de MSDN), pero la mayoría de la gente lo llama * el operador ternario. * :) –

Respuesta

39

DefaultIfEmpty debe ayudar:

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

En inglés: [DefaultIfEmpty] (http: // msdn.microsoft.com/en-us/library/bb355419.aspx) – Steve

+2

@Steve, gracias. Lo he editado, no dude en cambiarlo la próxima vez. – Snowbear

2

¿Qué tal:

int new_id = 0; 

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

no necesita un 'else' aquí ya que lo ha configurado en' 0' – hunter

+0

Es cierto, creo que soy anal acerca de ciertas cosas. ¡Los malos hábitos se mueren! –

+0

El principal problema con esta versión es que enumerará dos veces el iterador. El "Cualquiera" será la primera iteración y el "Máx" será el segundo. Esta implementación debe ser evitada. – srm

3

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

donde GetValueOrDefault es una method de Nullable<T>.

+3

Vale la pena señalar que solo Max() en las colecciones de tipos anulables devuelve nulo para la secuencia vacía, mientras que Max() en general arroja una excepción. – sluki