List.Remove(Item item) does not behave as expected

I am using Unity and trying remove duplicates from a List using a dictionary key/value pair.

ISSUE: When the code is run, IF there are duplicates, the first item in the list is deleted and NOT the specific item as "List.Remove(Item item)" should.

public static Dictionary<string, Farm> farmDict = new Dictionary<string, Farm>();
public static List<Farm> farmBuildingsList = new List<Farm>();

public static void UpdateList<T>(List<T> list, Dictionary<string, T> dict, string ID, T resBuilding) where T : ResourceBuildings, new()
    {
        T obj = new T()
        {
            ID = resBuilding.ID,
            hourlyIncome = resBuilding.hourlyIncome,
            baseHour = resBuilding.baseHour,
            incomeIncrement = resBuilding.incomeIncrement,
            totalSupply = resBuilding.totalSupply
        };

        if (dict.ContainsKey(ID))
        {
            dict[ID] = obj;
            list.Remove(dict[ID]);
            list.Add(dict[ID]);
        }
        else
        {
            dict.Add(obj.ID, obj);
            list.Add(obj);
        }
    }

Using Debug.Logs at the if statement, dict[ID] is null, but dict[ID].ID (and all the properties) contains the correct value, so the entire thing is not null. I am not sure if this is the issue, but I've asked for a solution on fixing Object.name within gamedev.stackexchange.

I've read on more appropriate ways (https://www.dotnetperls.com/duplicates and other stackoverflow posts) to remove duplicates using Linq and hashsets, but I can't figure out how to override Equals and HashCode functions.

1 answer

  • answered 2018-07-11 10:30 Rodrigo Rodrigues

    Short answer

    dict[ID] = new T
    {
        ID = resBuilding.ID,
        hourlyIncome = resBuilding.hourlyIncome,
        baseHour = resBuilding.baseHour,
        incomeIncrement = resBuilding.incomeIncrement,
        totalSupply = resBuilding.totalSupply
    };
    list.RemoveAll(item => item.ID == ID);
    list.Add(dict[ID]);
    

    Side note: dict[key] = value is enough to create a new element with the specified key or update an existing one (see the docs), so the whole if (dict.ContainsKey(ID)) is pointless.


    Extended answer

    Maybe this is a XY Problem, and your current approach could be hiding your real problem-to-be-solved (possibly: I want a dictionary-like structure that shows up in inspector).