Техническая часть: почему эта итерация не находит мой предмет - PullRequest
0 голосов
/ 11 марта 2011

Эй, люди вчера я работал над некоторым кодом и думал, что сохраню итерацию foreach и использую расширение find для объекта List <>, но так и не получил его. позже я реорганизовал код, чтобы использовать foreach с оператором lamda where, и это нашло мой элемент каждый раз.

Мои 2 версии кода размещены ниже:

Не рабочая версия:

private XmlCell FindCell(string id)
    {
        XmlSection section = new XmlSection(SectionNode);
        XmlCell currentCell = null;

        foreach (XmlBlock block in section.Blocks)
        {
            foreach (XmlRow row in block.Rows)
            {
                currentCell = row.Cells.Find(cell => string.Equals(cell.Id, id));
            }
        }

        Assert.IsNotNull(currentCell, string.Format("Cell with id {0} not found", id));
        return currentCell;
    }

рабочая версия:

XmlSection section = new XmlSection(SectionNode);
XmlCell currentCell = null;

foreach (XmlBlock block in section.Blocks)
{
    foreach (XmlRow row in block.Rows)
    {
        foreach (XmlCell cell in row.Cells.Where(cell => string.Equals(cell.Id, id)))
        {
            return cell;
        }
    }
}

Assert.IsNotNull(currentCell, string.Format("Cell with id {0} not found", id));
return currentCell;

может кто-нибудь plx объяснить, почему первый бит кода не выполняет работу, msdn говорит, что метод find возвращает первый экземпляр, который он находит в списке.

я даже сталкивался с ошибками "Коллекция была изменена; операция перечисления может не выполняться", почему?

Ответы [ 3 ]

2 голосов
/ 11 марта 2011

Поскольку следующая итерация снова сделает вашу переменную currentCell нулевой, когда Find не найдет ячейку с соответствующим идентификатором. Во втором фрагменте кода вы немедленно возвращаете найденную ячейку.

В первом фрагменте кода попробуйте это:

foreach (XmlRow row in block.Rows)
{
 currentCell = row.Cells.Find(cell => string.Equals(cell.Id, id));
 //new
 if (currentCell != null)
  return currentCell;
 //end new
}
1 голос
/ 11 марта 2011

Когда вы находите свою ячейку с указанным идентификатором, currentCell устанавливается для этого конкретного объекта. Однако на следующей итерации в цикле foreach значение currentCell устанавливается равным нулю, поскольку Find ничего не возвращает:)

 foreach (XmlRow row in block.Rows)
  {
     currentCell = row.Cells.Find(cell => string.Equals(cell.Id, id));
  }
0 голосов
/ 11 марта 2011

2 версии кода различаются - вторая возвращается из всех вложенных циклов, как только находит соответствующую ячейку, а первая возвращает наличие этой ячейки в последней строке последнего блока.

Исправлено - добавлена ​​проверка на нахождение ячейки во внутреннем цикле и повторный запуск, как только найдется ячейка:

foreach (XmlBlock block in section.Blocks)        
{  
    foreach (XmlRow row in block.Rows)             
    {                 
         currentCell = row.Cells.FirstOrDefault(cell => string.Equals(cell.Id, id));             
         if (currentCell != null) 
           return currentCell;

    }
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...