繁体   English   中英

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 个列表中不同的 object 因此,在列表 1中,总有 1 项不同,或者您只能在此列表中找到它。 我想比较 list1 和 list 2 并得到那个项目。 所以:

  • 该项目可以是仅在 list1 中而不在 list2 中的项目,请参见示例 1。
  • 该项目可以是与 list2 具有不同数量的项目,请参见示例 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 方法返回第一个列表中没有出现在第二个列表中的成员。

在您的情况下,这两个列表没有公共元素,因为元素是引用类型,并且它们的引用在第一个列表中与第二个列表中不同,尽管它们的值相同。

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

以下作品:

// 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();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM