C# 使用 Except 比较 2 个列表没有给出预期的结果

C# Comparing 2 lists using Except doesn't give expected result

所以我有 2 个列表:

...
List1= new ObservableCollection<Article>();
var List2= new List<Article>();

我想得到一个在我的 2 个列表中不同的对象。所以在 list 1 中总是有 1 个不同的项目 or 你只能在这个列表中找到它。我想比较 list1 和 list 2 并得到那个项目。 所以:

示例 1:

List1= new ObservableCollection<Article>();
var List2= new List<Article>();

List1.Add(new Article(1, "Cola", "1 x"));  
List1.Add(new Article(2, "Ice tea", "1 x"));  
List2.Add(new Article(1, "Cola", "1 x"));  

//Now I want to only get the ice tea back, that is the only difference in my 2 lists.

示例 2:

List1= new ObservableCollection<Article>();
var List2= new List<Article>();

List1.Add(new Article(1, "Cola", "1 x"));  
List1.Add(new Article(2, "Ice tea", "2 x"));  
List2.Add(new Article(1, "Cola", "1 x"));  
List2.Add(new Article(2, "Ice tea", "1 x"));  

//Now I want to only get the ice tea back with "2 x" fromlist 1, that is the only difference in my 2 lists.

我做了以下解决方案,但这不起作用,有人知道我做错了什么吗?

var OldArticles = List1;
var Newarticles = List2;
var PressedItem = OldArticles.Except(Newarticles).ToList();

对于所有必须比较的方法,您需要记住您的自定义 class 必须 override EqualsGetHashCode 有意义。一般来说,实现这两种方法是一种很好的做法,但如果您使用像 Enumerable.Except 这样的基于集合的方法,它首先使用 GetHashCode 然后使用 Equals.

则绝对有必要

另一种方法是在 class 中实现 IEquatable<Article> 并实现 Equals(和 GetHashCode)。最好同时执行这两项操作(见下文)。

第三个选项是实现自定义 IEqualityComparer<Article>,它有意义地实现 EqualsGetHashCode。您可以在许多 LINQ 方法(如 Except)的重载中使用它的一个实例。如果您不想更改文章的一般比较方式但仅适用于这种情况,请使用此选项。所以你可以有多种方式来比较文章。

假设有一个像 Id 这样的标识符:

public class Article: IEquatable<Article>
{
    // ...
    public int Id { get; }
    
    public bool Equals(Article other)
    {
        return other?.Id == Id;
    }
    
    public override bool Equals(object other)
    {
        return Equals(other as Article);
    }
    
    public override int GetHashCode()
    {
        return Id.GetHashCode();
    }
}

Enumerable.Except 方法 returns 第一个列表中没有出现在第二个列表中的成员。

在你的例子中,这两个列表没有共同的元素,因为元素是引用类型,它们的引用在第一个列表和第二个列表中是不同的,尽管它们的值相同。

在列表中添加元素时使用 Enumerable.Except 比较值类型或使用引用而不是 Add(new Article(1, "Cola", "1 x"))

以下作品:

// create elements
Article a1 = new Article(1, "Cola", "1 x");
Article a2 = new Article(2, "Ice tea", "1 x");
Article a3 = new Article(2, "Ice tea", "2 x");

// Example 1
List1.Add(a1);
List1.Add(a2);
List2.Add(a1);
var PressedItems = List1.Except(List2).ToList();

// Example 2
List1.Add(a1);
List1.Add(a3);
List2.Add(a1);
List2.Add(a2);
PressedItems = List1.Except(List2).ToList();