这引起的ArgumentOutOfRangeException是什么?

时间:2014-10-22 22:55:58

标签: c# list indexing argumentexception

我有一个让我疯狂的问题。我正在使用一个泛型List,每当我尝试将其第一个(或最后一个?)索引分配给变量时,它会抛出ArgumentOutOfRangeException。这是一大堆代码,因此我将尝试仅提取相关内容。所以这就是:

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);

            // ...
        }
    }
}

这就是我称之为方法的方式:

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
}

即使它不是一个非常详细的介绍正在发生的事情,因为我不得不切断一些复杂的代码,我真的希望别人可能会看到产生错误的原因。

非常感谢您至少看一眼!

修改

这是方法的样子。我没有改变任何东西,以显示其中的真实内容。我希望对某些人有意义:

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;
}

2 个答案:

答案 0 :(得分:5)

听起来你想要以下内容:

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);

            // ...
        }
    }
}

否则,由于rules.Count的大小未发生变化,您无限循环rules

todo为空之前一切正常,然后你得到异常,因为元素0不再存在,因为你已将它们全部删除了!

答案 1 :(得分:1)

你确定你不想要这个:

while(rules.Count != 0)
{
    string r = rules[0]; // <- Error 'ArgumentOutOfRangeException' here
    rules.RemoveAt(0);

你现在写的方式,你有一个实际上是无限的循环,除了你最终删除todo列表中的所有元素,此时你抛出例外(因为在空列表中,即使第0个元素也不存在)。