Set Operators in LINQ

Set operators are an important feature of LINQ (Language-Integrated Query) that allow developers to perform set-based operations on collections. In this lesson, we will discuss the set operators in LINQ and explore how they work in C#.

What are Set Operators in LINQ?

Set operators are used to perform set-based operations on collections in LINQ. The set operators in LINQ include Union, Intersect, Except, and Distinct. These operators are used to perform operations such as combining, intersecting, subtracting, and filtering data from collections.

Syntax: The syntax for using set operators in LINQ is as follows:

Union:

IEnumerable<TSource> Union<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);

Intersect:

IEnumerable<TSource> Intersect<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);

Except:

IEnumerable<TSource> Except<TSource>(this IEnumerable<TSource> first, IEnumerable<TSource> second);

Distinct:

IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source);

Where,

  • first: The first input collection to be processed.
  • second: The second input collection to be processed.
  • source: The input collection to be processed.
  • TSource: The type of the elements in the input collection.

Example: Consider the following example, where we have two collections of integers, and we want to retrieve the unique elements from the combined collection using the Union method.

int[] numbers1 = { 1, 2, 3, 4 };
int[] numbers2 = { 3, 4, 5, 6 };
var uniqueNumbers = numbers1.Union(numbers2);

foreach (var num in uniqueNumbers)
{
    Console.WriteLine(num);
}

Output:

1
2
3
4
5
6

Explanation: In the above example, we have two collections of integers with overlapping elements. We apply the Union method to the collections and store the result in a new variable called uniqueNumbers. The Union method combines the elements from both collections and returns only the unique elements. Finally, we iterate through the uniqueNumbers collection using a foreach loop and print each element to the console.

Custom Equality Comparer:

In some cases, the default equality comparer may not be suitable for comparing the elements in the collection. In such cases, we can provide a custom equality comparer to the set operators. The custom equality comparer should implement the IEqualityComparer<T> interface and provide a method for comparing the elements.

Example: Consider the following example, where we have two collections of Person objects, and we want to retrieve the unique elements based on the Person’s Name property using the Union method.

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
}

public class PersonNameEqualityComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {
        if (x == null || y == null)
            return false;

        return x.Name == y.Name;
    }

    public int GetHashCode(Person obj)
    {
        return obj.Name.GetHashCode();
    }
}

List<Person> people1 = new List<Person>
{
    new Person { Id = 1, Name = "John" },
    new Person { Id = 2, Name = "Jane" },
    new Person { Id = 3, Name = "Mary" },
    new Person { Id = 4, Name = "Peter" }
};

List<Person> people2 = new List<Person>
{
    new Person { Id = 5, Name = "Jane" },
    new Person { Id = 6, Name = "Peter"
};

var uniquePeople = people1.Union(people2, new PersonNameEqualityComparer());

foreach (var person in uniquePeople)
{
Console.WriteLine(person.Name);
}

Output:

John 
Jane 
Mary 
Peter

Explanation:
In the above example, we have two collections of Person objects with overlapping elements. We provide a custom equality comparer called PersonNameEqualityComparer that compares the Person objects based on their Name property. We apply the Union method to the collections and pass the custom equality comparer as an argument. The Union method compares the elements in the collections using the custom equality comparer and returns only the unique elements based on the Person’s Name property. Finally, we iterate through the uniquePeople collection using a foreach loop and print the Name property of each Person to the console.

Conclusion:
Set operators are a powerful feature of LINQ that allows developers to perform set-based operations on collections in C#. By using the Union, Intersect, Except, and Distinct methods, developers can easily combine, intersect, subtract, and filter data from collections. With the ability to provide custom equality comparers, set operators can be used to compare elements based on different criteria. By understanding how to use set operators in LINQ, developers can improve their skills and productivity in working with collections in their projects.