比较列表属性的相等性

3

我想要找到一个列表中,在一个属性上不同的项目数量,而这个属性本身是一个列表。我在这里找到了使用Linq的示例:

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

如果属性PersonId是标量的话,这种方法是有效的。但在我的情况下,这种方法不起作用,并且即使ListOfActions在所有项目中都相等,在下面SelectedTargets中返回的项始终是唯一的:

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>
    { ...

为什么不直接重写 ListOfActions 类的 Equals() 方法呢? - Tamas Ionut
请参见"问题标题中是否应包含“标签”?",共识是“不应该”! - user57508
好的。我会记住的。抱歉。 - packoman
2个回答

3
您可以使用自定义的 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 方法以实现有意义的对象比较,而不仅仅检查它们是否为同一引用。

我刚试了一下,它很好用,谢谢!但是我更喜欢一种解决方案,不需要实例化一个新对象(SequenceComparer)来测试相等性,这样Linq行就可以保持不变:List<Target> distinctTargets = SelectedTargets.GroupBy(p => p.ListOfActions).Select(g => g.First()).ToList(); 我重写了 Equals(IList<DispensingAction> obj) 并使用上述Linq行,但它返回 false。有什么建议吗? - packoman

1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接