使用Linq除了不按我的想法工作

Sch*_*mus 16 .net c# linq list except

List1包含项目{ A, B }List2包含项目{ A, B, C }.

我需要的是{ C }在使用Except Linq扩展时返回.相反,我得到了返回{ A, B },如果我在表达式中翻转列表,结果是{ A, B, C }.

我是否误解了Except的观点?还有其他我没有看到使用的扩展吗?

到目前为止,我已经查看并尝试了很多不同的帖子,但没有成功.

var except = List1.Except(List2); //This is the line I have thus far
Run Code Online (Sandbox Code Playgroud)

编辑:是的我正在比较简单的对象.我从未使用过IEqualityComparer,了解它很有趣.

谢谢大家的帮助.问题不是实现比较器.链接的博客文章和下面的示例有帮助.

Ufu*_*arı 17

如果要在列表中存储引用类型,则必须确保有一种方法可以比较对象是否相等.否则,将通过比较它们是否引用相同的地址来检查它们.

您可以IEqualityComparer<T>将其作为参数实现并发送到Except()函数.这是一篇你可能会发现有用的博客文章.


p.s*_*w.g 7

你只是混淆了参数的顺序.我可以看到这种混乱出现的地方,因为官方文档没有那么有用:

通过使用默认的相等比较器来比较值,生成两个序列的集合差异.

除非你精通集合论,否则可能并不清楚实际上集合的差异是什么- 它不仅仅是集合之间的不同之处.实际上,Except返回第一组中不在第二组中的元素列表.

试试这个:

var except = List2.Except(List1); // { C }
Run Code Online (Sandbox Code Playgroud)


Kev*_*vin 7

所以只是为了完整......

// Except gives you the items in the first set but not the second
    var InList1ButNotList2 = List1.Except(List2);
    var InList2ButNotList1 = List2.Except(List1);
// Intersect gives you the items that are common to both lists    
    var InBothLists = List1.Intersect(List2);
Run Code Online (Sandbox Code Playgroud)

编辑:由于您的列表包含对象,您需要为您的类传入IEqualityComparer ...以下是基于组合对象的示例IEqualityComparer的外观... :)

// Except gives you the items in the first set but not the second
        var equalityComparer = new MyClassEqualityComparer();
        var InList1ButNotList2 = List1.Except(List2, equalityComparer);
        var InList2ButNotList1 = List2.Except(List1, equalityComparer);
// Intersect gives you the items that are common to both lists    
        var InBothLists = List1.Intersect(List2);

public class MyClass
{
    public int i;
    public int j;
}

class MyClassEqualityComparer : IEqualityComparer<MyClass>
{
    public bool Equals(MyClass x, MyClass y)
    {
        return x.i == y.i &&
               x.j == y.j;
    }

    public int GetHashCode(MyClass obj)
    {
        unchecked
        {
            if (obj == null)
                return 0;
            int hashCode = obj.i.GetHashCode();
            hashCode = (hashCode * 397) ^ obj.i.GetHashCode();
            return hashCode;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)