簡體   English   中英

從HashSet獲取不同的值

[英]Get distinct values from HashSet

我只想從HashSet獲取不同的值,我已經實現了IEquatableIEqualityComparer ,但仍然無法獲取不同的值。

class Program
{
    static void Main(string[] args)
    {

        HashSet<Item> items = new HashSet<Item>()
        {
            {new Item("item1")},
            {new Item("item2")},
            {new Item("item3")},
            {new Item("item1")}
        };

        foreach (var item in items.Distinct())
        {
            Console.WriteLine(item.Name);
        }

        Console.ReadKey();

    }
}


class Item : IEquatable<Item>, IEqualityComparer<Item>
{
    public string Name { get; set; }
    public Item(string name)
    {
        this.Name = name;
    }

    public bool Equals(Item other)
    {
        return this.Name.Equals(other.Name);
    }

    public bool Equals(Item x, Item y)
    {
        return x.Equals(y);
    }

    public int GetHashCode(Item obj)
    {
        return this.Name.GetHashCode();
    }
}

控制台輸出:

item1
item2
item3
item1

謝謝!

如果只有一個實現定義類的相等性,則(適當地)實現IEquatable<T>就足夠了。 您也不應實現IEqualityComparer<T> 當您想提供多種方法來定義類型的兩個元素之間的唯一性時,后者通常意味着與單獨的類一樣。

除此之外,您對GetHashCode方法簽名是錯誤的。 當前,它順應object.Equals而不是您的自定義實現。

您需要將override關鍵字添加到您的GetHashCode實現中,並從簽名中刪除Item obj

public override int GetHashCode()
{
    return this.Name.GetHashCode();
}

並且重寫object.Equals也可以使用您的Equals(item other)

public override bool Equals(object obj)
{
    if (ReferenceEquals(null, obj)) return false;
    if (ReferenceEquals(this, obj)) return true;
    if (obj.GetType() != this.GetType()) return false;
    return Equals((Item) obj);
}

公共重寫bool Equals(您無需在HashSet<T>上調用Distinct() ,因為它提供了適當的IEquatable<T>重寫或為其提供了IEqualityComparer<T>

HashSet<T>.Add的文檔中

返回值:

類型:System.Boolean如果將元素添加到HashSet對象,則為true;否則為false。 如果該元素已經存在,則返回false。

首先,您應該將IEqualityComparer<T>作為一個單獨的類實現,並且需要在HashSet<T>構造過程中提供整個相等比較器:

var set = new HashSet<CustomClass>(new CustomClassEqualityComparer());

如果采用相等比較器方式,則不必強制實現IEquatable<T>

public class ItemEqualityComparer : IEqualityComparer<Item>
{
    public bool Equals(Item x, Item y)
    {
        return x.Name == y.Name;
    }

    public int GetHashCode(Item obj)
    {
        return obj.Name.GetHashCode();
    }
}

此外,您可以設計許多IEqualityComparer<T>實現,以涵蓋許多用例,這些用例可以為同一對象(即Item )定義不同的唯一性含義。

如果您提供了IEqualityComparer<T>的良好實現,那么您將不需要Distinct因為HashSet<T>是一個集合 ,這意味着它是唯一元素的無序集合,並且整個集合將使用相等比較器進行檢查如果給定的元素存在於該 (因此,所有的元素都在同一唯一!)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM