Reputation: 1262
I have a dictionary of type Dictionary<string, IEnumerable<string>>
and a list of string values. For some reason, every time I do an Add, every value in the dictionary is overwritten. I'm completely stumped as to why this is happening. I made sure it's not a reference problem be declaring and initializing the IEnumberable object within the loop so that it's scope does not go outside one iteration, and it still does it. Here is my code:
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);
}
where typelist
is an IEnumerable<string>
, root
is an XElement
, and serialLists
is my Dictionary.
Upvotes: 6
Views: 1469
Reputation: 54877
The reason is that your IEnumerable<string>
sequences are not being populated eagerly, but on-demand, after the foreach
loop would have completed all its iterations. Thus, when any IEnumerable<string>
sequence is enumerated, the type
variable would always have the value of the last element in typelist
.
Here is one easy way to fix it:
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);
}
Upvotes: 6
Reputation: 1062600
This is a captured iterator problem.
Try:
foreach (string tmp in typelist)
{
string type = tmp;
(and the rest unchanged)
Alternatively, I would evaluate the expression during the add, I.e. do a .ToList() in the .Add:
serialLists.Add(type, lst.ToList());
The second option is probably more effective overall, although it does force evaluation of thigs that might otherwise never be needed.
Upvotes: 10