C # List of duplicates

I am wondering why when I try not to add my object to the list when it duplicates it it adds it anyway

if (thePreviousList.Contains(thePreviousItem))
{
}
else
{
    thePreviousList.Add(thePreviousItem);
}

      

For example thepreviousitem id = 1 and name = test And if I have another object with the same name and same name, it will add it anyway ...

+3


source to share


5 answers


If you don't want to override Equals, you can use LINQ to check if an object with the same ID and name exists (which is not necessarily the same object):



if (thePreviousList.Any(item => item.ID == thePreviousItem.ID
                             && item.Name == thePreviousItem.Name)) 
{ 
} 
else 
{ 
    thePreviousList.Add(thePreviousItem); 
} 

      

+4


source


You need to correctly implement the method Equals

for the object you are trying to add to the list. To determine if the list contains a past object, the method Contains

uses Equals

.



+5


source


From the documentation:

This method determines equality using the default equality mapping as defined by the implementation of the IEquatable (Of T) .Equals method object for T (the type of values ​​in a list).

If you haven't implemented it IEquatable<T>.Equals

, it uses the default, which is referential equality. Also, you did IEquatable<T>.Equals

, but didn't do it right.

For example thepreviousitem id = 1 and name = test And if I have another object with the same name and same name, it will add it anyway ...

You need something like

class Foo : IEquatable<Foo> {
    public int Id { get; private set; }
    public string Name { get; private set; }
    public Foo(int id, string name) {
        this.Id = id;
        this.Name = name;
    }
    public bool Equals(Foo other) {
        return this.Id == other.Id && this.Name == other.Name;
    }
}

      

Finally, if checking for duplicates is something you are going to do a lot, then you shouldn't use List<T>

. You must use HashSet<T>

.

+4


source


Sounds from your comments on other answers that you don't want to override Equals

.

You can do this instead:

if (thePreviousList.Any(item => thePreviousItem.id == item.id && thePreviousItem.name == item.name))
{

}
else
{
    thePreviousList.Add(thePreviousItem);
}

      

+2


source


Because it List<>.Contains

checks references without checking the properties of the objects in the list.

For this, you must override Equals

, and for best practice, override GetHashCode

too. The rule should be that when it Equals

returns true, the same hash code should be returned.

It should be something like the following for you:

public override bool Equals(object obj)
{
   var i = obj as YourType;
   if(i == null) return false;

   return i.Id == this.Id && i.Name == this.Name;
}

public override int GetHashCode()
{
   return this.Id.GetHashCode() ^ this.Name.GetHashCode();
}

      

+1


source







All Articles