C # do.. while цикл для получения списка - PullRequest
0 голосов
/ 15 ноября 2018

Я хочу создать простое приложение, которое показывает рекурсивное членство в группах, но не пользователей, а групп. Поэтому, если groupA имеет groupB в качестве члена, а groupB имеет groupC в качестве члена, я хочу, чтобы код показывал мне все группы, вложенные до последней. Вот образец с тем, что у меня есть:

if (member.Any())
{
    List<string> tempGroup = new List<string>();
    do
    {
        tempGroup.Clear();
        foreach (object nestedGroup in member)
        {
            SearchResult NestedGroupMemberResult = null;
            try
            {
                string NestedgroupMemberSearchFilter = "(&(objectClass=group)(distinguishedName=" + nestedGroup.ToString() + "))";
                string NestedgroupMemberPropertise = "member,distinguishedName";
                NestedGroupMemberResult = dirSearcher(NestedgroupMemberSearchFilter, NestedgroupMemberPropertise);
            }
            catch { }
            if(NestedGroupMemberResult.Properties["member"].Count > 0)
            {
                foreach (object NestedGroupMember in NestedGroupMemberResult.Properties["member"])
                {
                    member.Add(NestedGroupMember.ToString());
                    tempGroup.Add(NestedGroupMember.ToString());
                }
            }
        }
    } while (!tempGroup.Any());
}

listBox1.DataSource = member;

По сути, член - это список, который содержит членов группы из входной группы. Допустим, я изначально поставил GroupA, и у него есть члены как GroupB и GroupC, и оба будут в списке участников. Теперь я хотел бы, чтобы этот цикл выполнялся ... пока он ищет каждого члена входной группы, используя примененный фильтр LDAP, и, если он найдет какую-либо группу, добавит его в список членов и список временных групп, поэтому каждый раз, когда есть вложенная группа, список членов будет обновляться и в то же время он будет включен в цикл foreach. Если приложение обнаружит, что вложенных групп больше нет, список временных групп будет пуст и цикл прекратится.

Однако я постоянно получаю сообщение об ошибке "System.InvalidOperationException: 'Коллекция была изменена; операция перечисления может не выполняться.'" Для

foreach (object nestedGroup in member)

И я думаю, что я не могу изменить список членов, пока цикл повторяется по нему. У меня был очень похожий цикл в powershell, который прекрасно работает, но я хотел иметь приложение на c #, так как знаю, что оно может быть намного быстрее при таких поисках.

Ответы [ 4 ]

0 голосов
/ 15 ноября 2018

Вы используете foreach, но это не позволяет вам изменять коллекцию.НО вы можете сделать обратный цикл for, например:

for (var i = list.Length - 1; i >= 0; i-- { var item = list[i]; // TODO }

Это должно работать.Просто замените все ваши петли foreach с модификацией коллекции на обратную for.

0 голосов
/ 15 ноября 2018

Не изменяйте коллекцию, которую вы перечисляете, с помощью foreach.Вместо этого вы можете собрать все, что вам нужно изменить:

List<Object> addMembers = new List<Object>();

foreach (object nestedGroup in member)
{
   // ...        
       foreach (object NestedGroupMember in NestedGroupMemberResult.Properties["member"])
        {
            addMembers.Add(NestedGroupMember.ToString());
            //...
        }
    }
    // ...
}

addMembers.ForEach(member.Add);
0 голосов
/ 15 ноября 2018

Существует несколько подходов, которые можно использовать для решения этой проблемы. Первый, использующий временный список, уже упоминался в ответах. Другой подход заключается в использовании for -loop. Как я уже говорил, MSDN утверждает следующее:

Оператор foreach используется для перебора коллекции, чтобы получить информация, которую вы хотите, но не можете использовать для добавления или удаления предметы из исходной коллекции, чтобы избежать непредсказуемых побочных эффектов. Если вам нужно добавить или удалить элементы из исходной коллекции, используйте для цикла.

Теперь здесь отсутствует некоторая информация, чтобы вы могли сделать правильный, наиболее подходящий выбор. Если вы используете for -loop и изменяете список во время перечисления, элементы, которые вы добавляете при перечислении, тоже будут перечисляться .

Поэтому задайте себе следующий вопрос: нужно ли перечислять вновь добавленные элементы? Если это так, используйте for -loop. Если нет, вы, вероятно, захотите использовать элементы где-то еще, и, следовательно, вам нужно хранить их где-то еще, например, во временном списке.

0 голосов
/ 15 ноября 2018

Пожалуйста, проверьте эту строку: member.Add(NestedGroupMember.ToString());

Возможно, произошла ошибка при выполнении этой строки, потому что вы пытаетесь добавить NestedGroupMember.ToString() в член список, который сейчас находится в цикле foreach , для устранения ошибки просто создайте временную переменную для этого типа так же, как определение tempGroup, а затем присоединить их к основному списку членов после окончания foreach.

...