Как перебрать коллекцию KeyValuePair

Я перебираю коллекцию KeyValuePair, затем копирую Ключ и Значение во вновь созданный класс следующим образом:

     Classes.MemberHierarchy membHier = new Classes.MemberHierarchy();
        List<Classes.MemberHierarchy> membHierList = new List<Classes.MemberHierarchy>();

        foreach (KeyValuePair<string, string[]> acct in acctData)
        {
            membHier.entityName = acct.Key;
            membHier.Accounts = acct.Value;
            membHierList.Add(membHier);                
        }

Проблема заключается в том, что после 2-й итерации свойства membHierList немедленно перезаписываются значениями в первой итерации. Это очень странно

Таким образом, при первой итерации membHier.entityName является "членом ABC", и учетные записи заполняются массивом строк без проблем.

Затем на 2-й итерации membHier.entityName является "членом XYZ".

Теперь "XYZ Member" занимает оба слота следующим образом

membHierList[0].base.entityName = "Член XYZ" membHierList[1].base.entityName = "Член XYZ"

Есть ли у меня конфликт объектов выше?

Заранее спасибо.... Боб

2 ответа

Решение

Нет, это не странно, потому что вы объявляете и инициализируете объект membHier только один раз до цикла, а затем попробуйте вставить в новый список тот же объект.

Это решит вашу проблему

    List<Classes.MemberHierarchy> membHierList = new List<Classes.MemberHierarchy>();

    foreach (KeyValuePair<string, string[]> acct in acctData)
    {
        Classes.MemberHierarchy membHier = new Classes.MemberHierarchy();
        membHier.entityName = acct.Key;
        membHier.Accounts = acct.Value;
        membHierList.Add(membHier);                
    }

Объявление НОВОГО экземпляра объекта MemberHierarchy каждый цикл будет заполнять список различными экземплярами, и каждый экземпляр имеет свои значения.
Вместо этого, с инициализацией вне цикла, на каждой итерации вы обновляете один и тот же экземпляр с извлеченными значениями. Но membHier является ссылочным типом, поэтому, если он не инициализирован повторно, он указывает на ту же память, в которой хранятся значения первого объекта, и вы фактически перезаписываете эти значения вторым объектом. В конце все элементы в списке указывают на одну и ту же ячейку памяти, и эти ячейки памяти содержат данные последней сущности

Вам нужно перенести строительство membHier к внутренней части цикла foreach. То, как ваш код написан сейчас, создается только один экземпляр класса MemberHierarchy.

List<Classes.MemberHierarchy> membHierList = new List<Classes.MemberHierarchy>();

foreach (KeyValuePair<string, string[]> acct in acctData)
{
    Classes.MemberHierarchy membHier = new Classes.MemberHierarchy();
    membHier.entityName = acct.Key;
    membHier.Accounts = acct.Value;
    membHierList.Add(membHier);                
}

используя текущий синтаксис C# 4.0 это будет выглядеть так:

var membHierList = new List<Classes.MemberHierarchy>();

foreach (var acct in acctData)
{
    membHierList.Add(new Classes.MemberHierarchy
    {
       entityName = acct.Key;
       Accounts = acct.Value;
    });
}
Другие вопросы по тегам