jshaf jshaf - 12 days ago 5
C# Question

Iterating over c# HashTable and changing the value. Additional information: Collection was modified; enumeration operation may not execute

I am trying to iterate over a HashTable and update the value provided it passes some conditions. Here is the code.

public static Hashtable AssembliesGlobal= new Hashtable();

public static void populateHash(){

NDepend.Path.IAbsolutePath assemblyName;
NDepend.Path.IAbsolutePath projectName;

for (int i = 0; i < someList.Count(); i++)
{

if (someList[i].AssembliesUsed.Count() > 0)
{
assemblyName = getAssemblyQuery[i].a.FilePath;
if (getAssemblyQuery[i].a.VisualStudioProjectFilePath != null)
{
List<IAbsolutePath> thirdPartyList = new List<IAbsolutePath>();
projectName = getAssemblyQuery[i].a.VisualStudioProjectFilePath;
thirdPartyList.Add(assemblyName);
AssembliesGlobal.Add(projectName, thirdPartyList);
}

}
}
}


public static void parseCsproj()
{

foreach (IAbsoluteFilePath key in AssembliesGlobal.Keys)
{
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load(key.FileInfo.FullName);
XmlNodeList references = xmldoc.GetElementsByTagName("ProjectReference");
XmlNodeList hintReferences = xmldoc.GetElementsByTagName("HintPath");
if (references.Count >= 1 || hintReferences.Count >= 1)
{
for (int i = 0; i < references.Count; i++)
{
string path = references[i].Attributes[0].Value;
if(path.Contains("3rdParty")){
AssembliesGlobal[key] = path;
}

}

for (int i = 0; i < hintReferences.Count; i++)
{
string path = hintReferences[i].InnerText;
if (path.Contains("3rdParty"))
{
AssembliesGlobal[key] = path;
}
}
}
}
}


AssembliesGlobal is a hashtable with the structure of:

AssembliesGlobal = {key => []}


I would like to append to the array that is the value of key. After running the debugger in VS I keep getting a Additional information: Collection was modified; enumeration operation may not execute. error. I am aware that you cannot iteratively update a HashTable and I am wondering what a work around may be in this context. I new to this language.

Answer

You can make a copy of the list to iterate over, by casting and adding a .ToList():

foreach (var key in AssembliesGlobal.Keys.Cast<IAbsoluteFilePath>().ToList())

Note that you need the .Cast because Hashtable is non-generic. As others have mentioned, the modern way to do this is Dictionary<K,V>.

Comments