对从 ICollection 对象创建的 List<> 执行操作 - 正在更改 ICollection 对象

Performing operations on a List<> created from ICollection objects - ICollection objects are being changed

我正在尝试创建一个字符串,其中包含由 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();
    }

看来你的PartUsed是一个class(例如reference type),所以u.PartsUsed其实是一些对象的引用集合,所以usedParts.Add(rep) 实际上是将相同的引用(对象)添加到 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>(假设 RepairPartQuantityint) 对于 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;
    }