Выполнение операций со списком List <>, созданным из объектов ICollection - объекты ICollection изменяются - PullRequest
2 голосов
/ 20 июня 2020

Я пытаюсь создать строку с частями и количествами из данных, содержащихся в ICollection. Я использую список для создания необходимых мне итогов, но когда я выполняю операции с этим списком, он фактически меняет значения в ICollection. Я не хочу, чтобы эти ценности менялись. Код следует. PartsUsed - это коллекция ICollection. Это потому, что добавление отдельных членов коллекции в список указывает только на исходные данные?

private string PartsDetails(out int totalCount, String modtype)
    {

        totalCount = 0;
        var str = new StringBuilder();
        var usedParts = new List<PartUsed>();
        var indexnum = 0;


        foreach (var u in Rma.AssociatedUnits)
        {
            if (u.PartsUsed != null && u.PartsUsed.Count > 0)
            {
                if ((modtype == "ALL"))
                {
                    foreach (var rep in u.PartsUsed)
                    {
                        if (!usedParts.Exists(x => x.Repair.Name == rep.Repair.Name))
                        {
                            usedParts.Add(rep);
                        }
                        else
                        {
                            usedParts[usedParts.FindIndex(f => f.Repair.Name == rep.Repair.Name)].RepairPartQuantity += rep.RepairPartQuantity;
                        }
                    }
                }
            }
        }

        foreach (var partsGroup in usedParts)
        {
            str.AppendFormat(str.Length > 0 ? Environment.NewLine + "{0} - {1}" : "{0} - {1}", partsGroup.RepairPartQuantity, partsGroup.Repair.Name);
            totalCount += partsGroup.RepairPartQuantity;
        }

        return str.ToString();
    }

1 Ответ

1 голос
/ 20 июня 2020

Кажется, что ваш PartUsed является классом (например, ссылочный тип ), поэтому u.PartsUsed на самом деле является набором ссылок на некоторые объекты, поэтому usedParts.Add(rep) фактически добавляет ту же ссылку ( object) на usedParts, и когда вы получаете и изменяете один из них в usedParts[usedParts.FindIndex(f => f.Repair.Name == rep.Repair.Name)].RepairPartQuantity += rep.RepairPartQuantity, вы фактически изменяете общий экземпляр. Это поведение можно также продемонстрировать следующим образом:

class MyClass { public int Prop { get; set; }   }

var ref1 = new MyClass{Prop = 1};
var ref2 = ref1;
ref2.Prop = 2;
Console.WriteLine(ref2.Prop);// prints 2

Один из способов - создать клон PartUsed для помещения в usedParts, но в вашем конкретном случае кажется, что вы можете использовать Dictionary<string, int> (при условии, что RepairPartQuantity равно int) для usedParts. Примерно так:

var usedParts = new Dictionary<string, int>();

.....
foreach (var rep in u.PartsUsed)
{
      if (!usedParts.ContainsKey(rep.Repair.Name))
      {
          usedParts[rep.Repair.Name] = rep.RepairPartQuantity;
      }
      else
      {
          usedParts[rep.Repair.Name] += rep.RepairPartQuantity;
      }
}

foreach (var kvp in usedParts)
    {
        str.AppendFormat(str.Length > 0 ? Environment.NewLine + "{0} - {1}" : "{0} - {1}", kvp.Value, kvp.Key);
        totalCount += kvp.Value;
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...