【问题标题】:LINQ Set Operations not working (Intersect, Except)LINQ 集操作不起作用(相交,除外)
【发布时间】:2011-01-28 07:06:21
【问题描述】:

我想用 LINQ 集合操作的 Uber-Coolness 来表达以下内容:

        foreach (Group group in groups)
        {
            if (user.Groups.Contains(group))
            {
                assignedGroups.Add(group);
            }
            else
            {
                availableGroups.Add(group);
            }
        }

我认为它应该是实现这一目标的两条线:

var assigned = user.Groups.Intersect(groups);
var available = groups.Except(user.Groups);

每当我运行此示例时,foreach 方法都会正确填充我的列表,而 set 操作会导致分配的空列表和已填充的可用列表。 我认为这一定是关于相等性检查的问题,但 Contains() 正在工作的事实证明这是错误的。 谁能帮我看看我的误解?

IEnumerable groups 也是 LINQ 查询的结果,以防万一该信息有帮助...

【问题讨论】:

  • Contains是你自己的方法,还是提供的?
  • 提供,这里没有个人风格
  • 对于交叉点没有任何区别,对于排除我没有尝试过,因为那没有任何意义。

标签: c# linq intersection


【解决方案1】:

嗯,它不应该有所作为,但从对称的角度来看,我会颠倒你创建assigned的方式。我还要确保查询只执行一次,并且剩余的操作发生在进程中:

var cachedGroups = groups.ToList();
var assigned = cachedGroups.Intersect(user.Groups);
var available = cachedGroups.Except(user.Groups);

一种可能性是user.Groups 有一个自定义相等比较器。这解释为什么 foreach 版本有效但 LINQ 版本无效。 user.Groups 的类型是什么,你对它使用的相等比较器了解多少?

【讨论】:

  • user.Groups 是基于 BindingList 类的自定义类型。我无法理解为什么列表的 Equality 比较器会有所不同(不是逐个元素进行比较吗?),但我可以确定 有一个自定义比较器。
  • 抱歉,这里弄错了:user.Groups 是 ObservableCollection。其余的如前所述有效
  • @Sebastian: Contains 仅使用 Equality 比较,而 Intersect 和 except 也使用 GetHashCode。如果散列和比较不一致,您可能会得到包含和相交/除外的不同行为。
  • @Konstantin:包含可能只使用相等。或者它也可能使用哈希码。这取决于集合是如何实现的。例如,HashSet 肯定会使用哈希码。我不知道 ObservableCollection ......但这是一个很好的观点,值得研究。一个损坏的 GetHashCode 方法可以解释这一点。
  • @Sebastian: 像这样:“Test.cs(3,14): 警告 CS0659: 'Test' 覆盖 Object.Equals(object o) 但不覆盖 Object.GetHashCode()”。永远不要忽视这样的警告!
猜你喜欢
  • 2023-03-07
  • 1970-01-01
  • 2019-08-20
  • 2014-03-09
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2011-01-16
  • 2018-06-22
相关资源
最近更新 更多