加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 使用IEqualityComparer和Equals / GethashCode Override有

发布时间:2020-12-15 06:46:22 所属栏目:百科 来源:网络整理
导读:当我使用词典时,有时我必须更改默认的等同含义才能比较键.我看到,如果我重写关键字类上的Equals和GetHashCode,或者我创建一个实现IEqualityComparer的新类,我有相同的结果.那么使用IEqualityComparer和Equals / GethashCode Override有什么区别? 两个例子:
当我使用词典时,有时我必须更改默认的等同含义才能比较键.我看到,如果我重写关键字类上的Equals和GetHashCode,或者我创建一个实现IEqualityComparer的新类,我有相同的结果.那么使用IEqualityComparer和Equals / GethashCode Override有什么区别?
两个例子:
class Customer
{
    public string name;
    public int age;
    public Customer(string n,int a)
    {
        this.age = a;
        this.name = n;
    }
    public override bool Equals(object obj)
    {
        Customer c = (Customer)obj;
        return this.name == c.name && this.age == c.age;
    }
    public override int GetHashCode()
    {
        return (this.name + ";" + this.age).GetHashCode();
    }
}
  class Program
{
    static void Main(string[] args)
    {
        Customer c1 = new Customer("MArk",21);
        Customer c2 = new Customer("MArk",21);
        Dictionary<Customer,string> d = new Dictionary<Customer,string>();
        Console.WriteLine(c1.Equals(c2));
        try
        {
            d.Add(c1,"Joe");
            d.Add(c2,"hil");
            foreach (KeyValuePair<Customer,string> k in d)
            {
                Console.WriteLine(k.Key.name + " ; " + k.Value);
            }
        }
        catch (ArgumentException)
        {
            Console.WriteLine("Chiave già inserita in precedenza");
        }
        finally
        {
            Console.ReadLine();
        }
    }
}

}

第二个 :

class Customer
{
    public string name;
    public int age;
    public Customer(string n,int a)
    {
        this.age = a;
        this.name = n;
    }
}
class DicEqualityComparer : EqualityComparer<Customer>
{
    public override bool Equals(Customer x,Customer y) // equals dell'equalitycomparer
    {
        return x.name == y.name && x.age == y.age;
    }
    public override int GetHashCode(Customer obj)
    {
        return (obj.name + ";" + obj.age).GetHashCode();
    }
}
class Program
{
    static void Main(string[] args)
    {
        Customer c1 = new Customer("MArk",21);
        DicEqualityComparer dic = new DicEqualityComparer();
        Dictionary<Customer,string>(dic);
        Console.WriteLine(c1.Equals(c2));
        try
        {
            d.Add(c1,string> k in d)
            {
                Console.WriteLine(k.Key.name + " ; " + k.Value);
            }
        }
        catch (ArgumentException)
        {
            Console.WriteLine("Chiave già inserita in precedenza");
        }
        finally
        {
            Console.ReadLine();
        }
    }
}

}

两个例子都有相同的结果.

提前致谢.

解决方法

当您重写Equals和GetHashCode时,您正在改变对象将如何确定它是否等于另一个.和一个注释,如果使用==运算符比较对象,它将不会与Equals具有相同的行为,除非你也覆盖运算符.

这样做你改变了一个类的行为,如果你需要与其他类相同的逻辑怎么办?如果您需要“通用比较”.这就是为什么你有IEqualityComparer.

看这个例子(full code on Github)

interface ICustom
{
    int Key { get; set; }
}
class Custom : ICustom
{
    public int Key { get; set; }
    public int Value { get; set; }
}
class Another : ICustom
{
    public int Key { get; set; }
}

class DicEqualityComparer : IEqualityComparer<ICustom>
{
    public bool Equals(ICustom x,ICustom y)
    {
        return x.Key == y.Key;
    }

    public int GetHashCode(ICustom obj)
    {
        return obj.Key;
    }
}

我有两个不同的类,都可以使用相同的比较器.

var a = new Custom { Key = 1,Value = 2 };
var b = new Custom { Key = 1,Value = 2 };
var c = new Custom { Key = 2,Value = 2 };
var another = new Another { Key = 2 };

var d = new Dictionary<ICustom,string>(new DicEqualityComparer());

d.Add(a,"X");
// d.Add(b,"X"); // same key exception
d.Add(c,"X");
// d.Add(another,"X"); // same key exception

请注意,我没有必要在两个类中都覆盖Equals,GetHashCode.我可以在实现ICustom的任何对象中使用此比较器,而无需重写比较逻辑.我也可以为“父类”创建IEqualityComparer,并在继承的类上使用.我可以让比较者以不同的方式表现,我可以让一个比较Value而不是Key.

所以IEqualityComparer允许更多的灵活性,你可以实现通用的解决方案.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读