The .Contains()
method uses the default equality comparer, which means it calls the .Equals()
method for the type to find a match.
For reference types like your Person
class, the default method inherited from Object
uses reference equality, meaning it will only return true
if they are the exact same object instance. If you want a different type of comparison, you should overload the Equals()
method in the type (and implement IEquatable<T>
and override GetHashCode()
while you're at it).
public class Person : IEquatable<Person>
{
public string Name {get; set;}
public int Age {get; set;}
public int Id {get; set;}
public bool Equals(Person other)
{
return other is Object && this.Id == other.Id;
}
public override bool Equals(Object other)
{
if (other is Person) return Equals((Person)other);
return false;
}
public override int GetHashCode()
{ //naive implementation. This is adequate as long as you're **SURE** all instances will have a unique/correct `Id` value.
return this.Id.GetHashCode();
}
}
Going beyond this, I would not build a separate PersonList
type. The List<Person>
generic collection almost certainly already does the things you need.
That out of the way, it's still worthwhile to address how you might implement the Exist()
method from the original PersonList
class. One thing I would do here is avoid trying to allocate new objects to complete the search. With that in mind:
public bool Exist(int inputParameter)
{
return personList.Any(p => p.Id == inputParameter);
}
Note, this will still currently allocate a new iterator object in most cases, but work is being done to make these linq operations more memory-friendly over time. It's also a whole lot less code. If you have a function that gives you a boolean
result, there's no good reason to put it in an if()
block just to return that same result.
And if we want to get really aggressive on the allocations, we can do it like this:
public bool Exist(int inputParameter)
{
foreach(var p in personList)
{
if (p.Id == inputParameter) return true;
}
return false;
}