2012-04-23 19 views
6

Tengo un diccionario de tipo Dictionary<string, IEnumerable<string>> y una lista de valores de cadena. Por alguna razón, cada vez que hago un Agregar, se sobrescribe cada valor en el diccionario. Estoy completamente perplejo de por qué esto está sucediendo. Me aseguré de que no fuera un problema de referencia declarar e inicializar el objeto IEnumberable dentro del ciclo para que su alcance no salga de una iteración, y todavía lo hace. Aquí está mi código:¿Por qué Dictionary.Add sobrescribe todos los elementos en mi diccionario?

foreach (string type in typelist) 
{ 
    IEnumerable<string> lst = 
     from row in root.Descendants() 
     where row.Attribute("serial").Value.Substring(0, 3).Equals(type) 
     select row.Attribute("serial").Value.Substring(3).ToLower(); 

    serialLists.Add(type, lst); 
} 

donde typelist es un IEnumerable<string>, root es un XElement y serialLists es mi diccionario.

+4

Usted ha "cerrado sobre la variable de bucle". Cada '' primer 'que agregue utilizará la variable * last * 'type'. Por favor, lea esto: http://blogs.msdn.com/b/ericlippert/archive/2009/11/12/closing-over-the-loop-variable-considered-harmful.aspx Curiosamente, este problema desaparecerá cuando llegue C# 5! – dlev

+1

Definitivamente leeré sobre eso. ¡Gracias de nuevo a todos por la ayuda! – Annath

Respuesta

10

Este es un problema de iterador capturado.

Probar:

foreach (string tmp in typelist) 
{ 
    string type = tmp; 

(y el resto sin cambios)

Alternativamente, me evaluar la expresión durante el complemento, es decir, hacer una .ToList() en el .Add:

    serialLists.Add(type, lst.ToList()); 

La segunda opción es probablemente más eficaz en general, aunque no forzar la evaluación de thigs que de otra manera no ser necesarios.

+0

¡Gracias! Eso solucionó el problema de inmediato. – Annath

6

La razón es que sus IEnumerable<string> secuencias no están siendo pobladas con impaciencia, pero bajo demanda, después de el bucle foreach habría completado todas sus iteraciones. Por lo tanto, cuando se enumera cualquier secuencia IEnumerable<string>, la variable type siempre tendrá el valor del último elemento en typelist.

Esta es una manera fácil de arreglar:

foreach (string type in typelist) 
{ 
    string typeCaptured = type; 

    IEnumerable<string> lst = 
     from row in root.Descendants() 
     where row.Attribute("serial").Value.Substring(0, 3).Equals(typeCaptured) 
     select row.Attribute("serial").Value.Substring(3).ToLower(); 

    serialLists.Add(typeCaptured, lst); 
} 
Cuestiones relacionadas