Reputation: 183
I have a problem that drives me nuts. I am using a generic List that throws an ArgumentOutOfRangeException whenever I try to assign its first (or last?) index to a variable. It's a pretty large pile of code, hence I'll try to extract only the relevant stuff. So here it is:
private string GetRuleByName(string name, List<string> rules)
{
if(rules != null)
{
List<string> todo = new List<string>();
todo.AddRange(rules);
while(rules.Count != 0)
{
string r = todo[0]; // <- Error 'ArgumentOutOfRangeException' here
todo.RemoveAt(0);
// ...
}
}
}
That's how I call the method:
void treeView_AfterSelect(object sender, TreeViewEventArgs e)
{
string currentRule = GetRuleByName(treeView.SelectedNode.FullPath, ruleCollection)
// the string list "ruleCollection" always contains
// strings and thus is never empty
}
Even though it's not a very detailed presentation of what's going on, as I had to cut off a piece of some complicated code, I really hope someone else might see what produces the error.
Big thanks in advance for at least having a look!
EDIT:
This is how the method looks like. I haven't altered anything, to show what's really inside it. I hope it makes sense for somebody:
private Rule GetRuleByNameOrId(string stName, List<Rule> rules)
{
if(rules != null)
{
string searchName = stName.ToLower().Trim();
string subName = "";
int slashPos = searchName.IndexOf('/');
if(slashPos != -1)
{
if(slashPos != searchName.Length)
subName = searchName.Substring(slashPos + 1);
searchName = searchName.Substring(0, slashPos);
}
List<Rule> todo = new List<Rule>();
todo.AddRange(rules);
while(todo.Count != 0)
{
Rule r = (Rule)todo[0];
todo.RemoveAt(0);
if(r.Name.ToLower() == searchName || r.Id.ToLower() == searchName)
{
if(subName != "")
{
Rule subRule = GetRuleByNameOrId(subName, r.Children);
if(subRule != null)
return subRule;
}
else
{
return r;
}
}
if(r.Children != null && r.Children.Count != 0)
todo.AddRange(r.Children);
}//end while
}//end if(rules != null)
return null;
}
Upvotes: 0
Views: 564
Reputation: 14012
Sounds like you want the following:
private string GetRuleByName(string name, List<string> rules)
{
if(rules != null)
{
List<string> todo = new List<string>();
todo.AddRange(rules);
while(todo.Count != 0) // <-- Minor mod here
{
string r = todo[0];
todo.RemoveAt(0);
// ...
}
}
}
Otherwise you are infinitely looping on rules.Count
as the size of rules
is not changing
This works fine until todo
is empty, then you get the exception because element 0 no longer exists as you've removed them all!
Upvotes: 5
Reputation: 70652
Are you sure you don't want this instead:
while(rules.Count != 0)
{
string r = rules[0]; // <- Error 'ArgumentOutOfRangeException' here
rules.RemoveAt(0);
?
The way you've written it now, you've got a loop that would actually be infinite, except that you eventually remove all the elements from the todo
list, at which point you throw the exception (because in an empty list even the 0-th element doesn't exist).
Upvotes: 1