2011-10-20 15 views
6

Sé que IEnumerable se ha debatido varias veces aquí, pero no he podido encontrar la respuesta a mi pregunta específica, por lo que lo planteo como una nueva pregunta.Enumeración múltiple de IEnumerable

Considere el siguiente fragmento de código:

static void Main(string[] args) 
    { 

     List<string> testList = new List<string> {"Test", "Test1", "Test1"}; 
     IEnumerable<string> filtered = testList.Where(x => x == "Test1"); 

     DoSomeWork(filtered); 
     DoSomeMoreWork(filtered); 
    } 

    public static void DoSomeWork(IEnumerable<string> items) 
    { 
     foreach (var item in items) 
     { 
      Console.WriteLine("do some work"); 
     } 
    } 

    public static void DoSomeMoreWork(IEnumerable<string> items) 
    { 
     foreach (var item in items) 
     { 
      Console.WriteLine("do some more work"); 
     } 
    } 

Estoy en lo cierto, esto provoca que no sólo las dos opciones de "filtrado" a iterar dos veces, pero en realidad los artículos en "LISTAPRUEBA"? Entonces, teniendo en cuenta que "testList" era una gran lista con 10000 ítems y "filtrado" lo reduce a 10 ítems, sería más inteligente hacer una lista "filtrada" (también conocida como var y anexar ToList() al final)

EDITAR: Esa es la pregunta más embarazosa que he hecho aquí. Sabía que sería malo iterar un IQueryable, por ejemplo, porque esto daría como resultado la obtención de los datos dos veces desde el DB. Sin embargo, no estaba exactamente seguro acerca de las listas de memoria. Me gustaría borrar la pregunta si podía ;-)

Lista

Respuesta

0

se heredan ultimatly de IEnumrable comprobar esto

public class List<T> : IList<T>, ICollection<T>, 
    IEnumerable<T>, IList, ICollection, IEnumerable 

Una cosa más que puede crear lista de IEnurable usando el siguiente constructor portarlo

public List(
    IEnumerable<T> collection 
) 

EDITAR

La lista derivedi.e filtrada es conseguir iterado dos veces por los métodos de ambos, pero appe nd Método .ToList() al final.

IEnumerable<string> filtered = testList.Where(x => x == "Test1").ToList(); 

http://msdn.microsoft.com/en-us/library/fkbw11z0.aspx

+0

Sí, lo sé. Pero la pregunta es.Will DoSomeWork() y DoSomeMoreWork() causan la iteración de la lista grande o solo iterarán en el subconjunto. – Christoph

+0

@Christoph - la respuesta está editada ahora ..... –

+0

Es mejor utilizar .ToArray que ToList para este uso: las matrices son algo más eficientes, pero lo más importante es que no permiten agregar/eliminar, evitando la flexibilidad innecesaria (evitando la confusión) y errores). –

1

La lista grande se reiteró dos veces. si no lo desea, puede "materializar" la restricción.

var filtered = testList.Where(x => x == "Test1").ToList(); 

Y hay muchas respuestas que le dicen esto. Usted debería haber buscado mejor :-)

0

sería más inteligente para hacer "filtrado" una lista (también conocido como utilizar var y simplemente anexar ToList() al final)

Sí, sobre todo en términos de Linq-To-Entities etc.

Volviendo a IEnumerable con linq permite la ejecución diferida. Cuando añada ToList() hasta el final, su lista se devuelve allí mismo.

Ver http://blogs.msdn.com/b/charlie/archive/2007/12/09/deferred-execution.aspx

7

La lista grande se reiteró dos veces. Para comprobar que esto sucede realmente cambiar la consulta a:

List<string> testList = new List<string> { "Test", "Test1", "Test1" }; 
IEnumerable<string> filtered = from t in testList 
           where t == "Test1" 
           select t; 

Si a continuación, establecer un punto de interrupción en la parte donde t ==' 'Prueba1', verá que el depurador llega esta línea, tanto para los iteraciones.

+0

Ah, sí. Está bien. ¡Gracias por la pista! – Christoph

Cuestiones relacionadas