更改集合中一项的值会影响所有重复项 [英] Changing value of one item in a collection affects all duplicate items
问题描述
我似乎遇到了一个奇怪的问题,即每次尝试更改集合中某项的值时,它都会影响所有包含相同初始值的其他项.
I seem to be having an odd issue whereby every time I try to change a value of an item in a collection, it affects all others that contain the same initial values.
下面是一个示例:
public class Product : ICloneable
{
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public Product()
{
Id = 0;
Quantity = 0;
}
public Clone()
{
return (Product)this.MemberwiseClone();
}
}
...
private static IEnumerable<Product> GetProducts(Product product, int quantity)
{
for (int i = 0; i < quantity; i++)
{
yield return product.Clone();
}
}
...
IEnumerable<Product> myProducts = Enumerable.Empty<Product>();
Product product1 = new Product() { Id = 0, Name = "Buzz Cola" };
Product product2 = new Product() { Id = 1, Name = "Choco Bites" };
myProducts = myProducts.Concat(GetProducts(product1, 2));
myProducts = myProducts.Concat(GetProducts(product2, 1));
//Now set the quantity of the first product to be 1.
myProducts.ElementAt(0).Quantity = 1;
foreach(Product product in myProducts)
{
Console.WriteLine(string.Format("Id: {0} Quantity: {1}", product.Id, product.Quantity));
}
//Output:
//Id: 0 Quantity: 1
//Id: 0 Quantity: 1 //NO!
//Id: 1 Quantity: 0
有什么想法吗?
非常感谢!
更新 我已按照建议将问题更新为包括Clone().输出仍然是相同的.
Update I have updated the question to include the Clone() as suggested. The output is still the same however.
推荐答案
您需要类似克隆方法或复制构造函数的内容.
You need something like a clone method or a copy constructor.
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public int Quantity { get; set; }
public Product()
{
this.Id = 0;
this.Name = null;
this.Quantity = 0;
}
public Product(Product product)
{
this.Id = product.id;
this.Name = product.Name;
this.Quantity = product.Quantity;
}
}
IList<Product> myProducts = new List<Product>();
Product product1 = new Product() { Id = 0, Name = "Buzz Cola" };
Product product2 = new Product() { Id = 1, Name = "Choco Bites" };
Product product3 = new Product(product1); // Use copy-constructor.
myProducts.Add(product1);
myProducts.Add(product2);
myProducts.Add(product3);
myProducts[0].Quantity = 1;
现在一切都很好.您可以将其与cloniung方法一起使用,一次生成大量克隆.
And now everything should be fine. You can use this together with your cloniung method to produce a large number of clones at once.
仅需注意,此代码的味道仍然很差-您正在创建具有相同ID的不同产品实例.我只能猜测,但是您是否要构建像购物车这样的东西,其中包含具有数量和产品的购物车项目?如果是,那么您应该真正考虑将产品类别分为两类.并考虑您的属性aganin的可访问性.
Just to note, this code has still a very bad taste - you are creating different product instances with equal ids. I can just guess, but do you want to build something like a shopping cart with cart items having a quantity and a product? If yes, you should really think about splitting the product class into two classes. And think about the accessibility of your properties aganin.
public class Product
{
public Int32 Id { get; private set; }
public String Name { get; private set; }
}
public class ShoppingCartItem
{
public Product Product { get; private set; }
public Int32 Quantity { get; set; }
}
public class ShoppingCart
{
public IList<ShoppingCartItem> Items { get; private set; }
}
这将解决您当前的问题,因为不再需要克隆产品.
This solves your current problems because there is no longer a need for cloning products.
这篇关于更改集合中一项的值会影响所有重复项的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!