C# 字符串比较时出现间歇性“超出范围”异常

C# 字符串比较时出现间歇性“超出范围”异常,c#,console-application,string-comparison,outofrangeexception,C#,Console Application,String Comparison,Outofrangeexception,环境:C、VS2012、SharePoint 2010 我正在使用一个控制台应用程序与SharePoint网站进行交互,并尝试对警报标题集合进行简单的字符串比较。。。但在调试时,有时会在特定字符串上出现超出范围的异常。下面是代码片段: // This is pointing to a txt file with two lines in it, "folder1" and "folder3" string[] aTitleList = System.IO.File.ReadAllLines(@"

环境:C、VS2012、SharePoint 2010

我正在使用一个控制台应用程序与SharePoint网站进行交互,并尝试对警报标题集合进行简单的字符串比较。。。但在调试时,有时会在特定字符串上出现超出范围的异常。下面是代码片段:

// This is pointing to a txt file with two lines in it, "folder1" and "folder3"
string[] aTitleList = System.IO.File.ReadAllLines(@"c:\path\to\specific\file.txt");
// Now we iterate through all the alerts to compare titles against those two lines
for (int i = oAlertCollection.Count - 1; i > -1; i--)
{
    System.Guid guid = oAlertCollection[i].ID;
    foreach (string sTitle in aTitleList)
    {
        if (oAlertCollection[i].Title.Contains(sTitle))
        {
            // At this point it throws the exception on the sTitle string
            // But ONLY on "folder3" and ONLY about half of the time
            // If I change it to something other than "folder3" it works 100%
        }
    }
}
其他人觉得这很奇怪吗?在这个应用程序中,我有很多其他方法可以进行类似的比较,而且没有问题,即使在使用folder3字符串时,也只有在使用这个特定数组时才会遇到问题

编辑1-循环的深入解释:本例中的循环是删除与给定字符串匹配的项。循环的设置方式是,它从最后一个项目开始,并不断迭代,直到达到0。这是因为SharePoint会自动向下移动集合中每个项目的ID,以替换已删除的项目,因此没有间隙。这也是它获取Count方法的地方,查看集合中编号最高的ID。澄清一下:Count方法返回警报总数,但实际警报ID从0开始,因此for循环在使用i对它们进行索引之前调整计数。如果Count方法返回0个元素,for循环将其设置为-1,并且不触发

编辑2-测试结果:我一直在对应用程序进行电池测试,虽然我仍然无法找到它在阵列中使用2个项目时工作/爆炸的一致性,但我发现了一些可能有助于解释原因的东西。如果我将数组增加到3项,它将始终失败。当第一个或第二个字符串比较为true且该项被删除时,就会出现问题,因为foreach循环不会在该点退出,它会继续根据现在不存在的警报测试其余字符串,该警报会引发异常。当数组中只有两项发生这种情况时,在第一项触发删除后测试第二项并不总是引发异常。有一半的时间,它会测试已删除的警报,就像它仍然存在一样,并继续主循环

作为参考,这是如何工作的解释。它可能会在删除警报后短暂地将其保存在内存中吗?这是我看到它不会在每次测试已删除警报时抛出异常的唯一方法

最终编辑:问题回答得很好,删去的部分仍然没有回答,但最终与情况无关。

正如Jim Mischel所指出的,只有当您碰巧从循环中的oAlertCollection中删除元素时,才会发生以下情况

我冒着风险假设您的oAlertCollection有时可以容纳0个元素,这就是为什么您的代码在这一行崩溃的原因

if (oAlertCollection[i].Title.Contains(sTitle))
然后,您将尝试访问数组中的位置-1,该位置引发outofrange异常

在像这样循环之前,可以通过检查oAlertCollection.Count的值来避免这种情况

if(oAlertCollection.Count() > 0)
{
    //for loop
}

这样,如果它实际上包含0个元素,则可以避免错误,因为它不会进入循环

oAlertCollection如何获得其计数?oAlertCollection.Count是否可以为0?请考虑当oAlertCollection为空时,i的值是多少。只需使用LINQ和foreach var alert:oAlertCollection.Reverse。还有,我会去掉匈牙利语,这对于局部变量来说是毫无意义的。是的,这很奇怪。您是否能够捕获异常并查看i是否在0..oAlertCollection.Count-1范围内?你是不是碰巧从oAlertcollection中删除了一些东西?如果我上面的猜测是错误的,你还需要做更多的诊断。只有当感觉没有什么可继续的时候。您还没有告诉我们i和oAlertCollection的值在错误发生的点上是什么,甚至没有告诉我们它发生在哪一行。顺便说一句,linq的可读性要高得多:oAlertCollection.where=>aTitleList.Containsa.Title{/…}只有当他从循环中的某个地方的OAlerCollection中删除项时,才会发生这种情况。我想这就是原因。谢谢你的建议,我会试一试以防万一。但是,当抛出异常时,我总是包含一个正值。然后可能我包含一个高于oAlertCollection的值。计数-1,这也会抛出一个异常。我刚刚检查了它的每个场景,问题确实与我高于计数-1有关,但有一个扭曲。。。在评论中解释太多了,所以我将把它编辑成问题。