繁体   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