簡體   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