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

标签 c# .net

好吧,这有点难问,但我会试试。 我有一个包含对象(Lots)的列表,其中再次包含一个包含对象(Wafers)的列表。 当我更改晶圆内的值时,它将在两个列表中更改!这就是我想要的。 但是当我想从复制列表中删除晶圆时,它不应该从原始列表中删除。所以我想在每个批处理中都有一个新的晶圆列表,但是对晶圆的引用应该与原始批处理中的相同,因为我想更改晶圆的值并且它应该更改原始晶圆和复制晶圆中的值.没有深拷贝可能吗?

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

    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;
    }

我希望它没有那么困惑?我希望我的问题得到足够好的解释。

最佳答案

我想我可以在这里看到您的问题。在您的 CopyList 中,您有效地克隆了列表,即

lot.Wafers = new List<Wafer>(lot.Wafers);

但是,这里要注意的关键点是 Lot 对象的引用 仍然是相同的 - 因此您实际上是在克隆和替换 Wafers 原始列表中的属性。

当你打电话时

copyList.RemoveAt(1);

这很好,因为您正在操作 Lot 列表 的副本。但是,当您调用

copyList[0].Wafers.RemoveAt(0);

您正在修改 Lot instance,它仍被两个列表引用。要解决此问题,您需要克隆 Lot 对象本身以有效更改引用,即

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)
    });
}

因此,您将失去 Lot 对象本身的两个列表中的自动更新,但您仍会保留它以修改单个 Wafer 对象(作为引用因为他们不会改变)。

总而言之,您实际上要问的是:

How can I keep the same object reference whilst having a different property reference?

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

关于c# - 是否可以在不丢失原始引用的情况下删除列表列表中的项目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16733097/

相关文章:

c# - .NET 5.0 或 .NET Framework 3.5 用于在 Windows 7+ 上部署?

c# - 从 C# 中的 DataSet 中提取存储过程 COUNT 结果

c# - 仅运行 .Net 2.0 与 3.5 我错过了什么?

asp.net - WinForms和ASP.NET自定义控件的通用代码

asp.net - 使用名称很长的文件发布项目

c# - Crystal 报表。使用 MVC 的 Windows Server 2008 中的 "cannot find the path specified"

c# - 如何获取 ASP.NET 应用程序的根文件夹

c# - 为什么 System.Runtime.InteropServices._Exception 不遵循 .NET 中接口(interface)的标准命名约定?

c# - 如果捕获一般异常,是否有可能出现异常?

c# - "C# compiler as a service "的状态是什么