Willie Marais
Willie Marais

Reputation: 33

List<T>.Remove does not remove Object

I am implementing the following code to remove an item from a list

// RemoveRole is a member function in a class for Person
// roles is defined as 
// List<PersonOrganisationRoleModel> roles;
// And properly populated prior to this function call

public void RemoveRole(string RoleName)
{
    // I am creating an object that needs to be matched in the list
    PersonOrganisationRoleModel role = new PersonOrganisationRoleModel(OrganisationID, PersonID, RoleName)

    // "role" is now properly constructed, and is matching an exact copy of one of the objects in "roles"
    // the expectation now is the the object "role" must be matched with one of the objects in "roles",
    // and that one be removed
    roles.Remove(role);

}

But the "Remove" function call on the "roles" list does not remove the item in the list that contains the exact same values.

My understanding is that this is supposed to work (it is just the inverse of List.Add

Upvotes: 1

Views: 317

Answers (2)

Guy
Guy

Reputation: 50819

You need to override Equals() in PersonOrganisationRoleModel class, otherwise the Remove() will compare the objects by reference, which will be false since role is a new object

public override bool Equals(object obj)
{
    if (obj == null)
    {
        return false;
    }

    PersonOrganisationRoleModel p = obj as PersonOrganisationRoleModel;
    if (p == null)
    {
        return false;
    }

    return this.OrganisationID == p.OrganisationID && this.PersonID == p.PersonID;
}

If you are using dictionaries or sets to store this object you should also override GetHashCode()

public override GetHashCode()
{
    return OrganisationID.GetHashCode() ^ PersonID.GetHashCode();
}

Upvotes: 3

Danial Kalhori
Danial Kalhori

Reputation: 173

The reason is that your role object is not a member of the list and has a different address on memory. By the way if you override Equals method ,like above , you are able to use that. You can also remove via LINQ like this example.

roles.RemoveAll(r => r.OrganisationID == OrganisationID && r.PersonID == PersonID)

This remove all objects in the list by this OrganisationID and PersonID.

Upvotes: 4

Related Questions