Reputation: 33
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
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
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