简体   繁体   中英

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. I populate this with a method, a few other bits then Add it to the Range of another List named itemDataList.

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!

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. 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. 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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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