In this article we’ll present and compare two functions which offer us a possibility to check whether an item exists in a given list. These functions are Exists and Contains, both available in System.Collections.Generic namespace. Provided examples are for two different lists: one containing integers and other one containing objects of custom created class.
List of integers
For the purpose of this article, let’s create an example list containing few integers.
1 |
var items = new List<int>() { 1, 2, 3, 5, 8, 13, 21 }; |
Exists method
Exists function receives a predicate as an argument and returns bool representing the result of given formula. Predicate can be either simple comparison of two objects or really complicated equation. Returned value is true when list contains at least one item which meets defined criteria. No matter if one item is matched or multiple, the result will be the same.
1 |
public bool Exists (Predicate<T> match); |
1 2 3 |
var result1 = items.Exists(x => x == 8); // result1 = true var result2 = items.Exists(x => x == 4); // result2 = false var result3 = items.Exists(x => x > 5 && x < 20); // result3 = true |
Contains method
Contains behavior is similar to Exists, however instead of a predicate, it receives an argument which is actual value to be checked. The result type is the same, which is a bool indicating whether given item is in the list or not.
1 |
public bool Contains (T item); |
1 2 |
var result4 = items.Contains(5); // result4 = true var result5 = items.Contains(10); // result5 = false |
List of custom objects
Now, let’s create a class which will be used to present examples of usage Exists and Contains with custom defined objects.
1 2 3 4 5 |
public class Person { public string Forename { get; set; } public string Surname { get; set; } } |
Having a class, we can create a list of Person objects and populate it with few entities.
1 2 3 4 5 6 |
var items = new List<Person>() { new Person() { Forename = "John", Surname = "Smith" }, new Person() { Forename = "Laura", Surname = "Jones" }, new Person() { Forename = "Tom", Surname= "Wilson" } }; |
Exists method
The usage of Exists function is very similar as in list with integers. It’s required to provide a predicate which will be executed against items list to verify whether any item is matched. Again, predicate might be simple or extended formula.
1 2 3 4 5 6 |
var r1 = items.Exists(x => x.Forename == "Laura"); // r1 = true var r2 = items.Exists(x => x.Forename == "John" && x.Surname == "Wilson"); // r2 = false var r3 = items.Exists(x => x.Surname == "Smith" || x.Surname == "Wilson"); // r3 = true |
Contains method
Contains method expects a Person object to be passed as a parameter.
Below we’ve created an object p1 where forename is Laura and surname is Jones. Even though such person exists on a list, we still get result r4 = false. It’s because the object we passed is not exactly the same instance as the one added to the list.
Another object, p2 is assigned as a second item from the list. This time Contains method returns true, because that object’s instance actually exists on the list.
1 2 3 4 5 6 7 8 9 |
var p1 = new Person() { Forename = "Laura", Surname = "Jones" }; var r4 = items.Contains(p1); // r4 = false var p2 = items[1]; var r5 = items.Contains(p2); // r5 = true |
If we’d like to change the way how objects are compared, we can easily do it by implementing IEquatable interface and defining our custom Equal function.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
public class Person : IEquatable<Person> { public string Forename { get; set; } public string Surname { get; set; } public bool Equals(Person? other) { if (other == null) { return false; } if (Forename == other.Forename && Surname == other.Surname) { return true; } return false; } } |
If we run below code again, this time we get both results as true. Having custom comparer function, we don’t care anymore whether two objects are exactly the same instances. Now objects are considered to be the same if both forenames and surnames are equal.
1 2 3 4 5 6 7 8 9 |
var p1 = new Person() { Forename = "Laura", Surname = "Jones" }; var r4 = items.Contains(p1); // r4 = true var p2 = items[1]; var r5 = items.Contains(p2); // r5 = true |