betaFlux
betaFlux

Reputation: 183

What is this ArgumentOutOfRangeException caused by?

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

Answers (2)

Charleh
Charleh

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

Peter Duniho
Peter Duniho

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

Related Questions