简体   繁体   English

更改添加到列表的项目(AddRange)更改添加到AddRange的表

[英]Items added to List (AddRange) are changed when the table added to AddRange is changed

I would expect this to happen if I initiating my temp list outside the loop, but I am not so do not understand why I am getting the result I am. 我希望如果在循环外启动临时列表会发生这种情况,但是我不是很不明白为什么我得到了我想要的结果。 My code is essentially: 我的代码本质上是:

foreach (DataRow dtRow in dt.Rows)
{
    List<IItemData> tempTable = new List<IItemData>();
    tempTable = CreateCopyOfTemplate(item, new List<IItemData>(), tableTemplate, itemDataList, item.Id, tableSortOrder);

    foreach (IItemData itemData in tempTable)
    {
        if (itemData.Content.StartsWith("cdt:") && itemData.DataSource.Description == nameof(DataSource.CustomDataTableValue))
        {
            itemData.Content = dtRow[itemData.Content.Replace("cdt:", "")].ToString();
        }
    }

    tableSortOrder++;
    itemDataList.AddRange(tempTable.ToList());
}


private static List<IItemData> CreateCopyOfTemplate(IItemData itemData, List<IItemData> newTable, List<IItemData> templateTable, List<IItemData> originalTable, int? origParentId, int tableSortOrder)
{
    List<IItemData> childList = templateTable.Where(x => x.ParentId == origParentId).ToList();

    if (itemData.DataSource != null && itemData.DataSource.Description == nameof(DataSource.CustomDataTable))
    {
        itemData.Id = originalTable.Max(x => x.Id) + 1;
        itemData.SortOrder = tableSortOrder;
        newTable.Add(itemData);
    }

    foreach (IItemData childItem in childList)
    {
        origParentId = childItem.Id;
        childItem.ParentId = itemData.Id;
        childItem.Id = newTable.Max(x => x.Id) + 1;
        newTable.Add(childItem);

        CreateCopyOfTemplate(childItem, newTable, templateTable, originalTable, origParentId, tableSortOrder);
    }

    return newTable;
}

Where on each pass of the ForEach loop I create a new List<IITemData> named tempTable. 在ForEach循环的每个遍历中的什么地方,我创建一个名为tempTable的新List<IITemData> I populate this with a method, a few other bits then Add it to the Range of another List named itemDataList. 我用一种方法填充它,然后再将其添加到另一个名为itemDataList的List的Range中。

I have firstly initiated the tempTable list within the loop and have also used ToList() when applying to the main list however the records added in on the first pass of the loop are all updated with the values of the second pass of the loop - thus ending up with duplicate data in my list! 我首先在循环内启动了tempTable列表,并且在应用于主列表时也使用了ToList(),但是在循环的第一遍添加的记录都用循环的第二遍的值进行了更新-因此最终得到我列表中的重复数据!

I get the feeling I am missing something obvious but it has been a long day and just cannot figure it out. 我感觉到我缺少明显的东西,但这已经是漫长的一天,只是无法弄清楚。

So I'm not 100% sure, but it looks like you are reusing the "item" object in each pass of the foreach loop, you make some changes to it in CreateCopyOfTemplate, and then add it to newTable and return it. 因此,我不确定100%,但是您似乎在foreach循环的每个遍历中都在重复使用“ item”对象,您在CreateCopyOfTemplate中对其进行了一些更改,然后将其添加到newTable并返回它。 Only to pass it in again, make some changes and return it. 只是要再次传递它,进行一些更改然后将其返回。 Ultimately using the same reference 最终使用相同的参考

if (itemData.DataSource != null && itemData.DataSource.Description == nameof(DataSource.CustomDataTable))
{

    itemData.Id = originalTable.Max(x => x.Id) + 1;
    itemData.SortOrder = tableSortOrder;
    newTable.Add(itemData); <-- Here you keep adding the same item
}

You could instantiate a new instance of an object implementing IItemData and use that instead. 您可以实例化实现IItemData的对象的新实例,并改用它。 An easy way might be to deep copy the object there or just manually set all the properties. 一种简单的方法可能是将对象深复制到那里,或者只是手动设置所有属性。

Look here: https://docs.microsoft.com/en-us/dotnet/api/system.object.memberwiseclone?view=netframework-4.7.2 看这里: https : //docs.microsoft.com/zh-cn/dotnet/api/system.object.memberwiseclone?view=netframework-4.7.2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM