通过list属性比较相等性

时间:2016-01-22 10:11:07

标签: c# linq list

我试图找到列表中的项目数量,这些项目本身就是一个列表。我使用Linq here找到了这个例子:

List<Person> distinctPeople = allPeople
  .GroupBy(p => p.PersonId)
  .Select(g => g.First())
  .ToList();

如果属性PersonId是标量,这很有效。但在我的情况下,这不起作用,在下文中SelectedTargets中的项目总是以不同的方式返回,即使ListOfActions在所有项目中都相同:

List<Target> distinctTargets = SelectedTargets.GroupBy(p => p.ListOfActions).Select(g => g.First()).ToList();

如果我选择ListOfActions中的第一项,则可以使用:

List<Target> distinctTargets = SelectedTargets.GroupBy(p => p.ListOfActions[0]).Select(g => g.First()).ToList();

那么如何检查整个列表ListOfActions是否相等? (它不一定要用户Linq)

SelectedTargets的定义是:

List<Target> SelectedTargets = new List<Target>();

并且是DispensingActionList:

private DispensingActionList ListOfActions = new DispensingActionList();
public class DispensingActionList : List<DispensingAction>
    { ...

2 个答案:

答案 0 :(得分:2)

您可以使用自定义IEqualityComparer<T>进行比较序列的GroupBy重载。例如,这使用Enumerable.SequenceEqual

public class SequenceComparer<T> : IEqualityComparer<IEnumerable<T>>
{
    public bool Equals(IEnumerable<T> x, IEnumerable<T> y)
    {
        if (x == null && y == null) return true;
        if (x == null || y == null) return false;

        var comparer = EqualityComparer<T>.Default;
        return x.SequenceEqual(y, comparer);
    }

    public int GetHashCode(IEnumerable<T> items)
    {
        unchecked
        {
            int hash = 17;
            foreach (T item in items)
            {
                hash = hash * 23 + (item == null ? 0 : item.GetHashCode());
            }
            return hash;
        }
    }
}

现在这应该有效:

 List<Target> distinctTargets = SelectedTargets
    .GroupBy(p => p.ListOfActions, new SequenceComparer<DispensingAction>())
    .Select(g => g.First())
    .ToList();

当然DispensingAction还需要覆盖Equals来有意义地比较对象,而不仅仅是检查它们是否是相同的引用。

答案 1 :(得分:1)

您可以使用Enumerable.SequenceEqual<TSource>

如果您尚未覆盖类型的GetHashCodeEquals方法,则必须覆盖这些方法。