如果我想要两个列表中的公共元素,我可以使用交叉函数:
var listC = listA.Intersect(listB);
但这比较对象。如果列表中有Persons类型的对象,并且我想获得具有相同名称的人,例如,我该怎么做?我在哪里设置name属性的条件?
感谢。
答案 0 :(得分:3)
传递自定义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));
等等。