2011-05-29 14 views

Respuesta

24
  1. .First() arrojarán una excepción si la lista fuente no contiene elementos. See the Remarks section. Para evitar esto, use FirstOrDefault().

  2. .ElementAt(0) arrojará una excepción si el índice es mayor o igual que el número de elementos en la lista. Para evitar esto, use ElementAtOrDefault(0). Si está utilizando LINQ to SQL, esto no se puede traducir a sql, mientras que .First() se puede traducir a TOP 1.

  3. El indexador también lanzará una excepción si el índice es mayor o igual que el número de elementos en la lista. No ofrece una opción OrDefault para evitar esto, y no se puede traducir a sql para LINQ To SQL. EDIT: olvidé mencionar la simple obviedad de que si su objeto es un IEnumerable, no puede usar un indexador como este. Si su objeto es una Lista real, entonces está bien.

+1

re: punto2 - Personalmente prefiero tener un índice de excepción rango que una referencia nula - los xOrDefault() métodos son malos! – MattDavey

+2

@MattDavey Me explico por mi cuenta que los métodos OrDefault necesitan una verificación nula. No causan excepciones de referencia nula, la mala codificación sí lo hace. – ProfK

+1

@ProfK No dije que causaron excepciones de referencia nula. Dije que preferiría tener una IndexOutOfRangeException que una referencia nula. Es una preferencia personal, por supuesto, pero no encuentro referencias nulas útiles de ninguna manera. – MattDavey

1

No, no hay diferencia en absoluto. Todos hacen lo mismo, devuelven el primer elemento de la lista.

EDIT: Supongo que no debería decir que no hay diferencia. ElementAt() y First() tienen un control de errores que lo hacen, verificando nulos e índices fuera de rango, pero en realidad no debería ser notable.

6

En el caso "válido" (es decir, cuando una lista tiene al menos un elemento), son los mismos que señala APShredder. Si no hay elementos, entonces list[0] y list.ElementAt(0 lanzarán un ArgumentIndexOutOfRangeException, mientras que list.First() arrojarán un InvalidOperationException.

6

Otra consideración para elegir entre estas opciones es que First() y ElementAt(0) son ambos compatibles con cualquier secuencia - cualquier aplicación de IEnumerable. (Esto puede ser útil ya que significa que puede intercambiar su variable con una implementación diferente de IEnumerable sin tener que cambiar ningún código). Por el contrario, el indexador solo funciona para listas y otras estructuras que implementan directamente esa funcionalidad.

Por el contrario, usar el indexador puede ser una buena manera de garantizar (en tiempo de compilación) que está optimizando el rendimiento, ya que ElementAt tiene una posibilidad razonable de ser O (n) en lugar de O (1) mientras que los indexadores suelen se supone que es rápido.

11

Quizás una pregunta anterior, pero hay una diferencia de rendimiento.

para el código de abajo:

var lst = new List<int>(); 

      for (int i = 0; i < 1500; i++) 
      { 
       lst.Add(i); 
      } 
      int temp; 


      Stopwatch sw1 = new Stopwatch(); 

      sw1.Start(); 

      for (int i = 0; i < 100; i++) 
      { 
       temp = lst[0];  
      } 


      sw1.Stop(); 




      Stopwatch sw2 = new Stopwatch(); 
      sw2.Start(); 
      for (int i = 0; i < 100; i++) 
      { 
       temp = lst.First(); 
      } 

      sw2.Stop(); 

      Stopwatch sw3 = new Stopwatch(); 
      sw3.Start(); 
      for (int i = 0; i < 100; i++) 
      { 
       temp = lst.ElementAt(0); 
      } 

      sw3.Stop(); 

obtendrá los siguientes tiempos (en las garrapatas):

sw1.ElapsedTicks

sw2.ElapsedTicks

sw3.ElapsedTicks

+1

Esto debería ser votado más, creo –

Cuestiones relacionadas