Прерывистое исключение "вне диапазона" при сравнении строк
Среда: 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 автоматически сдвигает идентификатор каждого элемента в коллекции, заменяя тот, который был удален, чтобы не было пробелов, это также где он получает Count
метод, глядя на самый высокий номер ID в коллекции). Уточнить: Count
Метод возвращает общее количество оповещений, но фактические идентификаторы оповещений начинаются с 0, поэтому for
цикл регулирует количество перед использованием i
индексировать их. Если Count
метод возвращает 0 элементов, for
цикл устанавливает это в -1 и не срабатывает.
Редактировать 2 - Результаты теста: я тестировал приложение на аккумуляторе, и, хотя я до сих пор не могу найти соответствие между тем, как оно работает / бомбится при использовании двух элементов в массиве, я обнаружил нечто, что может пролить свет на причину. Если я увеличу массив до 3 элементов, он не будет работать последовательно. Проблема возникает, когда сравнение первой или второй строки выполняется и элемент удаляется, потому что foreach
Цикл не завершается в этой точке, он продолжает тестировать оставшиеся строки в соответствии с уже несуществующим предупреждением, которое выдает исключение. Когда это происходит только с двумя элементами в массиве, тестирование второго элемента после того, как первый вызвал удаление, не всегда вызывает исключение. Половину времени он "проверяет" удаленное предупреждение, как если бы оно все еще было, и продолжает основной цикл.
Для справки, это объяснение того, как работает SPAlertCollection. Может быть, это может кратковременно удерживать предупреждение в памяти даже после его удаления? Это единственный способ увидеть, что он НЕ выдает исключение каждый раз, когда проверяет удаленное предупреждение.
Окончательное редактирование: на вопросы даны ответы достаточно хорошо, зачеркнутый раздел до сих пор остается без ответа, но в конечном итоге не имеет отношения к ситуации.
1 ответ
Как отметил Джим Мишель, следующее может произойти, только если вы удалите элементы из oAlertCollection
в вашей петле
Я выхожу на конечности и принимаю ваше oAlertCollection
иногда может содержать 0 элементов, поэтому ваш код падает на этой строке
if (oAlertCollection[i].Title.Contains(sTitle))
Затем вы пытаетесь получить доступ к позиции -1 в массиве, который вызывает исключение за пределами диапазона
Вы можете избежать этого, проверив oAlertCollection.Count
значение перед циклом, как это
if(oAlertCollection.Count() > 0)
{
//for loop
}
Таким образом, если на самом деле он содержит 0 элементов, вы избежите ошибки, потому что она не войдет в цикл