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