Ok this is a little bit hard to ask, but i will try. I have a List with objects (Lots), which contains again a list with objects (Wafers). When i change a value within a wafer it will be changed in both lists! Thats what i want. But when i want to remove a wafer from the copied list, it should not be removed from the orginal list. So i want to have a new List of wafers in each lot but the references to the wafers should be the same as in the original lot because i want to change values to the wafers and it should change the values in the orginal wafer and copied wafer. Is it possible without deep copy?
I have the following code, to explain it better:
public class Lot
{
public string LotName { get; set; }
public List<Wafer> Wafers { get; set; }
}
public class Wafer
{
public string WaferName { get; set; }
}
[Test]
public void ListInListTest()
{
//Some Testdata
List<Lot> lotList = new List<Lot>();
Lot lot = new Lot();
lot.LotName = "Lot1";
lot.Wafers = new List<Wafer>();
Wafer wafer = new Wafer();
wafer.WaferName = "Wafer1";
lot.Wafers.Add(wafer);
wafer = new Wafer();
wafer.WaferName = "Wafer2";
lot.Wafers.Add(wafer);
wafer = new Wafer();
wafer.WaferName = "Wafer3";
lot.Wafers.Add(wafer);
wafer = new Wafer();
wafer.WaferName = "Wafer4";
lot.Wafers.Add(wafer);
lotList.Add(lot);
lot = new Lot();
lot.LotName = "Lot1";
lot.Wafers = new List<Wafer>();
wafer = new Wafer();
wafer.WaferName = "Wafer1";
lot.Wafers.Add(wafer);
wafer = new Wafer();
wafer.WaferName = "Wafer2";
lot.Wafers.Add(wafer);
wafer = new Wafer();
wafer.WaferName = "Wafer3";
lot.Wafers.Add(wafer);
wafer = new Wafer();
wafer.WaferName = "Wafer4";
lot.Wafers.Add(wafer);
lotList.Add(lot);
//Copy the List
List<Lot> copyList = CopyList(lotList);
//That works. It removes the lot just in the copyList but not in
//the original one
copyList.RemoveAt(1);
//This works not like i want. It removes the wafers from the copied list
//and the original list. I just want, that the list will be changed
//in the copied list
copyList[0].Wafers.RemoveAt(0);
}
private List<Lot> CopyList(List<Lot> lotList)
{
List<Lot> result = new List<Lot>(lotList);
foreach (Lot lot in result)
{
lot.Wafers = new List<Wafer>(lot.Wafers);
}
return result;
}
I hope it is not so confusing? And i hope my question is explained good enough.
I think I can see what your issue is here. In your CopyList
you effectively clone the list i.e.
lot.Wafers = new List<Wafer>(lot.Wafers);
However, the key point to note here is the reference to the Lot
object is still the same - so effectively you are cloning & replacing the Wafers
property on the original list as well.
When you call
copyList.RemoveAt(1);
that's fine because you are manipulating a copy of the Lot
list. However, when you call
copyList[0].Wafers.RemoveAt(0);
you are modifying the Lot
instance which is still being referenced by both lists. To solve the problem you would need to clone the Lot
object itself to effectively change the reference i.e.
List<Lot> result = new List<Lot>(lotList.Count);
foreach (Lot item in lotList)
{
result.Add(new Lot()
{
LotName = item.LotName,
Wafers = new List<Wafer>(item.Wafers)
});
}
As a result you would lose the automatic update in both lists for the Lot
object itself but you would still retain it for modifying the individual Wafer
objects (as the reference for them wouldn't have changed).
So to summarise, what you are effectively asking is:
How can I keep the same object reference whilst having a different property reference?
The answer to that question is - you can't.
As far as I can see, there is no out-of-the-box way for you to do what you want. Here is a brief description why:
The List<Lot>
(far left-hand-side) contains a reference to the Lot
object, which in turn contains references to both its member variables.
If you want changes to the LotName
and constituents of the Wafers
list to be propagated as you describe, the easiest solution is to share a reference to the Lot
object between lists:
Now you can see why it is impossible to modify the items in the list of Wafers
independently using this solution - you can't get away from the fact that you are using the same object reference!
By sharing a reference you lose the ability to control how differences in behaviour. To achieve what you want, I think you have to do a deep copy of the Lot
instances, and you could then manage the propagation of changes through some sort of Observer pattern.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With