C# 是否可以在不丢失原始引用的情况下删除列表中的项目?

C# 是否可以在不丢失原始引用的情况下删除列表中的项目?,c#,.net,C#,.net,好的,这有点难问,但我会试试。 我有一个包含对象(批次)的列表,其中再次包含一个包含对象(晶圆)的列表。 当我改变晶圆中的一个值时,它在两个列表中都会改变!这就是我想要的。 但当我想从复制列表中删除晶圆时,它不应该从原始列表中删除。所以我想在每个批次中都有一个新的晶片列表,但对晶片的引用应该与原始批次中的相同,因为我想更改晶片的值,它应该更改原始晶片和复制晶片中的值。如果没有深度复制,这可能吗 为了更好地解释,我有以下代码: public class Lot {

好的,这有点难问,但我会试试。 我有一个包含对象(批次)的列表,其中再次包含一个包含对象(晶圆)的列表。 当我改变晶圆中的一个值时,它在两个列表中都会改变!这就是我想要的。 但当我想从复制列表中删除晶圆时,它不应该从原始列表中删除。所以我想在每个批次中都有一个新的晶片列表,但对晶片的引用应该与原始批次中的相同,因为我想更改晶片的值,它应该更改原始晶片和复制晶片中的值。如果没有深度复制,这可能吗

为了更好地解释,我有以下代码:

    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;
    }
公共类地块
{
公共字符串LotName{get;set;}
公共列表晶圆{get;set;}
}
公共级晶圆
{
公共字符串WaferName{get;set;}
}
[测试]
public void ListInListTest()
{
//一些测试数据
List lotList=新列表();
批次=新批次();
lot.LotName=“Lot1”;
lot.Wafers=新列表();
晶圆=新晶圆();
wafer.WaferName=“Wafer1”;
批次。晶圆。添加(晶圆);
晶圆=新晶圆();
wafer.WaferName=“Wafer2”;
批次。晶圆。添加(晶圆);
晶圆=新晶圆();
wafer.WaferName=“Wafer3”;
批次。晶圆。添加(晶圆);
晶圆=新晶圆();
wafer.WaferName=“Wafer4”;
批次。晶圆。添加(晶圆);
lotList.Add(批次);
批次=新批次();
lot.LotName=“Lot1”;
lot.Wafers=新列表();
晶圆=新晶圆();
wafer.WaferName=“Wafer1”;
批次。晶圆。添加(晶圆);
晶圆=新晶圆();
wafer.WaferName=“Wafer2”;
批次。晶圆。添加(晶圆);
晶圆=新晶圆();
wafer.WaferName=“Wafer3”;
批次。晶圆。添加(晶圆);
晶圆=新晶圆();
wafer.WaferName=“Wafer4”;
批次。晶圆。添加(晶圆);
lotList.Add(批次);
//复制列表
List copyList=复制列表(lotList);
//这很有效。它只会删除复制列表中的部分,而不会删除复制列表中的部分
//原版
复制列表。删除(1);
//这与我想要的不一样。它会从复制列表中删除晶圆
//还有原来的名单。我只是想,名单会改变
//在复制的列表中
复制列表[0]。晶圆。移除(0);
}
私有列表CopyList(列表lotList)
{
列表结果=新列表(lotList);
foreach(结果中的批次)
{
lot.Wafers=新列表(lot.Wafers);
}
返回结果;
}

我希望它不是那么混乱?我希望我的问题得到足够好的解释。

问题是,通过维护对主列表的引用来创建克隆列表。您应该使用以下内容:

private List<Lot> CopyList(List<Lot> list)
{
   List<Lot> clone = new List<Lot>();

   foreach(Lot l in list)
   {
      List<Wafer> wafers = new List<Wafer>();
      foreach(Wafer w in l.Wafers)
         wafers.Add(w);

      clone.Add(new Lot(){ LotName = l.LotName, Wafers = wafers });
   }

   return clone;
}
private List copyrist(列表)
{
列表克隆=新列表();
foreach(清单中的l标段)
{
列表晶圆=新列表();
foreach(在l晶片中为w晶片)
晶片。添加(w);
添加(新批(){LotName=l.LotName,Wafers=Wafers});
}
返回克隆;
}

简短回答:是的,这是可能的。但是,CopyList方法应该如下所示

private List<Lot> CopyList(List<Lot> lotList)
{
    List<Lot> result = new List<Lot>();

    for (int i = 0; i < lotList.Count; i++)
    {
         Lot lot = new Lot();
         lot.LotName = lotList[i].LotName;
         lot.Wafers = new List<Wafer>(lotList[i].Wafers);
         result.Add(lot);
    }

    return result;
}
私有列表复制列表(列表lotList)
{
列表结果=新列表();
for(int i=0;i

这将创建一个新的lotlist,并将所有现有的晶圆添加到其中。

据我所知,没有现成的方法可以让您随心所欲。以下是原因的简要说明:

列表
(最左侧)包含对
批次
对象的引用,而该对象又包含对其两个成员变量的引用

如果您希望对
LotName
Wafers
列表的成分进行更改,如您所述,最简单的解决方案是在列表之间共享对
Lot
对象的引用:

现在,您可以了解为什么不可能使用此解决方案单独修改
晶圆列表中的项目了-您无法摆脱使用相同对象引用的事实


通过分享推荐信,你失去了控制行为差异的能力。为了实现您想要的,我认为您必须对
批次
实例进行深度复制,然后您可以通过某种模式管理更改的传播。

我想我可以看到您的问题所在。在您的
复制列表中
可以有效地克隆列表,即

lot.Wafers = new List<Wafer>(lot.Wafers);
这很好,因为您正在操作
Lot
列表的副本。然而,当你打电话时

copyList.RemoveAt(1);
copyList[0].Wafers.RemoveAt(0);
您正在修改两个列表仍在引用的
批次
实例。要解决此问题,您需要克隆
批次
对象本身以有效地更改引用,即

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)
    });
}
List结果=新列表(lotList.Count);
foreach(批次列表中的批次项目)
{
结果。添加(新批次()
{
LotName=item.LotName,
晶圆=新列表(项目.晶圆)
});
}
因此,您将丢失
批次
对象本身在两个列表中的自动更新,但您仍将保留它以修改单个
晶圆
对象(因为它们的参考不会更改)

总之,你要问的是:

如何在具有不同属性引用的同时保留相同的对象引用


这个问题的答案是-你不能。

你应该为列表使用两个单独的变量,例如
ListLotA
ListLotB
。如果您希望能够删除

List<Lot> ListLotA = new List<Lot>();

Wafer w1 = new Wafer() { WaferName = "w1" };
Wafer w2 = new Wafer() { WaferName = "w2" };
Wafer w3 = new Wafer() { WaferName = "w3" };

ListLotA.Wafers.Add(w1);
ListLotA.Wafers.Add(w2);
ListLotA.Wafers.Add(w3);

List<Lot> ListLotB = new List<Lot>();

// At this point adding w1, w2, w3 to the second list is possible, but let's
// assume it's not and you have to copy them from the first list.
Wafer[] wArray = new Wafer[ListLotA.Wafers.Count];
ListLotA.Wafers.CopyTo(wArray);

ListLotB.Wafers.AddRange(wArray);
ListLotB.Wafers[1].WaferName = "New Value";
ListLotA.Wafers.Remove(w2);