Question

If I want the common elements in two list, I can use the intersect function:

var listC = listA.Intersect(listB);

But this compare objects. If the lists have objects of type Persons and I would like to get the persons with the same name for example, how could I do that? Where I set the condition of the name property?

Thanks.

Was it helpful?

Solution

Pass it a custom IEqualityComparer<T>.

First, make a class that implements that interface:

public class PersonNameEqualityComparer:IEqualityComparer<Person>
{
    public int GetHashCode (Person obj)
    {
        return obj.Name.GetHashcode ();
    }
    public bool Equals (Person x, Person y)
    {
        return x.Name == y.Name;
    }
}

Then, all you need to do is pass an instance of that IEqualityComparer to the intersect method.

var result = listA.Intersect(listB, new PersonNameEqualityComparer());

You could extend this to any object and any property, using generics and lambdas:

public class PropertyEqualityComparer<TObject, TProperty> : IEqualityComparer<TObject>
{
    Func<TObject, TProperty> _selector;
    IEqualityComparer<TProperty> _internalComparer;
    public PropertyEqualityComparer(Func<TObject, TProperty> propertySelector, IEqualityComparer<TProperty> innerEqualityComparer = null)
    {
        _selector = propertySelector;
        _internalComparer = innerEqualityComparer;
    }
    public int GetHashCode(TObject obj)
    {
        return _selector(obj).GetHashCode();
    }
    public bool Equals(TObject x, TObject y)
    {
        IEqualityComparer<TProperty> comparer = _internalComparer ?? EqualityComparer<TProperty>.Default;
        return comparer.Equals(_selector(x), _selector(y));
    }
}

You could then just use it like this:

var result = listA.Intersect(listB, new PropertyEqualityComparer<Person, string>(p => p.Name));

or like this:

var result = listA.Intersect(listB, new PropertyEqualityComparer<Person, string>(p => p.Age));

and so on.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top