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.
An example is below:
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
Any ideas?
Many thanks!
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.
And now everything should be fine. You can use this together with your cloniung method to produce a large number of clones at once.
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.
This solves your current problems because there is no longer a need for cloning products.