如何根据属性的值选择公共元素

本文关键字:选择 元素 何根 属性 | 更新日期: 2023-09-27 18:17:39

如果我想要两个列表中的公共元素,我可以使用intersect函数:

var listC = listA.Intersect(listB);

但是这个比较对象。如果列表有person类型的对象,而我想获得具有相同名字的person,我该怎么做呢?在哪里设置name属性的条件?

谢谢。

如何根据属性的值选择公共元素

传递一个自定义的IEqualityComparer<T>

首先,创建一个实现该接口的类:

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;
    }
}

然后,您所需要做的就是将该IEqualityComparer的一个实例传递给intersect方法。

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

你可以使用泛型和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));
    }
}

你可以这样使用它:

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

或者像这样:

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