Object Comparison in .net

2020-04-21 18:15发布

Is it any different from the CLR standpoint to implement IEqualityComparer vs overriding the == operator for the property you would use in the IEqualityComparer<T>? And if so, when would you use one against the other?

Edit

Ok it does make sense that the IEqaulityComparer used by the implementations of Hashtable - it slipped out of my mind when I was posting the question. So what about the extensions of Linq of IEnumerable. Does that mean that .net builds up a Hashtable when executing those kind of extension methods?

3条回答
在下西门庆
2楼-- · 2020-04-21 18:38

IEqualityComparer is not equal, equal is for object (instance method) but EqualityComparer is for decoration for example in linq you want do specific distinct:

personList.OrderBy(p=>p.ID).Distinct(new MyEqualityComparer())

and

  class MyEqualityComparer: IEqualityComparer<Person>
  {

    public bool Equals(Person p1, Person p2)
    {
       if (p1.Age == p2.Age)
          return true;
       return false;
    }


    public int GetHashCode(Person p)
    {
        return p.Id.GetHashCode();
    }

  }

but equal is for Person:

public class Person
{
 public int ID{get;set;}
 public int Age{get;set;}
 public override bool Equals(object o)
 {
   //do stuff
 }
}

you can do any number of decoration by IEqualityComparer but you can't do this by instance method (you can write personList.Distinct(new AnotherComparer) ,...)

查看更多
叼着烟拽天下
3楼-- · 2020-04-21 18:38

IEqualityComparer is used for example for comparison in Dictionary<TK,TV>.

It is completely different from overriding == operator because actually Dictionary (and in general whatever use IEqualityComparer) doesn't make any call to == operator.

At most, you can compare "implementing IEqualityComparer " vs "overriding GetHashCode and Equals methods", because indeed they're two ways to get the same thing (and I would say they're equal to me).

查看更多
Viruses.
4楼-- · 2020-04-21 19:02

IEqualityComparer is used by the Hashtable, NameValueCollection and OrderedDictionary classes in order to support a custom definition of "equality" for your types. That's why it provides GetHashCode(), which doesn't have much to do with equality per se.

If you don't provide an IEqualityComparer, the classes mentioned above will default to Object.Equals(), which implements reference equality. An overloaded operator == won't be called in that context.

EDIT: Some LINQ's extension methods indeed take an IEqualityComparer as an argument, but the principle remains the same: if that argument is not specified, the method will end up comparing references, not values, and operator == won't be called.

查看更多
登录 后发表回答