C#索引超出范围String数组和List<string>。

7

在尝试了几种错误检查方法后,我得出结论需要帮助来解决这个问题。

我为什么没有捕获到 "索引超出范围" 错误。为了良好的实践,我可以采取什么措施避免这个问题再次发生?

    public void loadFromFile()
    {
        OpenFileDialog oFile = new OpenFileDialog();
        oFile.Title = "Open text file";
        oFile.Filter = "Text Files (*.txt)|*.txt|All Files (*.*)|*.*";
        oFile.FilterIndex = 1;
        oFile.InitialDirectory = Application.StartupPath;
        oFile.AddExtension = true;
        oFile.CheckFileExists = true;
        oFile.CheckPathExists = true;

        // Open and clean Duplicates
        String[] lines;
        List<string> temp = new List<string>();
        List<string> newlist = new List<string>();

        if(oFile.ShowDialog() == DialogResult.OK)
        {
            // Dummy file has 6 lines of text. Filename:DuplicatFile.txt
            // 3 duplicate lines and 3 not.
            lines = File.ReadAllLines(oFile.FileName, System.Text.Encoding.UTF8);

            // Copy array to temporary array
            for (int index=0; index < lines.Length; index++)
            {
                // System.ArgumentOutOfRangeException was unhandled
                // Index was out of range. Must be non-negative and less than the size of the collection.
                if (lines[index].Length >= 0)
                {
                    temp[index] = lines[index];
                }
            }
            // Check for duplicates. If duplicate ignore if non-duplicate add to list.
            foreach (string line in temp)
            {
                if (!newlist.Contains(line))
                {
                    newlist.Add(line);
                }
            }
            // Clear listbox and add new list to listbox.
            lstBox.Items.Clear();
            foreach (string strNewLine in newlist)
            {
                lstBox.Items.Add(strNewLine);
            }
        }
    }
4个回答

8
List<string> temp = new List<string>();
...
temp[index] = lines[index];

temp起始大小为0。任何索引都超出范围。

您可以通过使用temp.Add使列表动态增长来解决此问题:

temp.Add(lines[index]);

我应该知道的!干得好!我完全忽略了那个!谢谢你的建议,我会尽量坚持那种方法。 - Nightforce2

2

Mud 对于 ArgumentOutOfRangeException 给出了正确的答案。您可以使用 Linq 简化 if 语句中的所有代码,如下所示:

lines = File.ReadAllLines(oFile.FileName, System.Text.Encoding.UTF8);    
lstBox.Items.AddRange(lines.Distinct().ToArray());

但如果我这样做,它怎么会去掉重复的内容呢? - Nightforce2
调用Distinct()将消除任何重复的行。请查看文档以获取更多信息http://msdn.microsoft.com/en-us/library/bb348436.aspx。 - sgriffinusa
我喜欢这个想法,但它给了我一个错误。“无法将'System.Collections.Generic.IEnumerable<string>'转换为'object[]'”。 - Nightforce2
已更新答案,将IEnumerable更改为数组。现在应该可以工作了。 - sgriffinusa
这还是非常简短的!运行得相当不错!感谢您的帮助。 - Nightforce2

1
问题不在于“行”索引超出了范围 - 而是“temp”索引超出了范围... 你创建了一个名为“temp”的新列表,但里面什么都没有... 它的长度为0!
你应该使用 .Add 方法而不是从一个索引复制到另一个索引:
temp.Add(lines[index])

当然,有更好的方法来复制一个数组,但这是最接近你上面提出的问题并直接回答你的问题的方法。


1
你之所以会得到这个错误,是因为在列表temp中没有该索引处的元素。(temp为空)。你可以使用temp.Add(value)来填充它。
另一种创建临时列表的方法是使用temp = newlist.ToList()
我建议使用LINQ:你可以使用

lstBox.Items.Clear();
foreach (var line in lines.Distinct())
    lstBox.Items.Add(line);

而不是所有这段代码:

// Copy array to temporary array
for (int index=0; index < lines.Length; index++)
{
    // System.ArgumentOutOfRangeException was unhandled
    // Index was out of range. Must be non-negative and less than the size of the collection.
    if (lines[index].Length >= 0)
    {
        temp[index] = lines[index];
    }
 }
 // Check for duplicates. If duplicate ignore if non-duplicate add to list.
 foreach (string line in temp)
 {
   if (!newlist.Contains(line))
   {
       newlist.Add(line);
   }
 }
 lstBox.Items.Clear();
 foreach (string strNewLine in newlist)
 {
    lstBox.Items.Add(strNewLine);
 }

简单来说:


我以前不知道那个。Linq我不经常使用。我会尝试更多地使用它。 - Nightforce2
Linq是一个很棒的东西,你可以看一下。生活会变得更加光明)) - The Smallest

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接