10

How can I make the Distinct() method work with a list of custom object (Href in this case), here is what the current object looks like:

public class Href : IComparable, IComparer<Href>
{
    public Uri URL { get; set; }
    public UrlType URLType { get; set; }

    public Href(Uri url, UrlType urltype)
    {
        URL = url;
        URLType = urltype;
    }


    #region IComparable Members

    public int CompareTo(object obj)
    {
        if (obj is Href)
        {
            return URL.ToString().CompareTo((obj as Href).URL.ToString());
        }
        else
            throw new ArgumentException("Wrong data type.");
    }

    #endregion

    #region IComparer<Href> Members

    int IComparer<Href>.Compare(Href x, Href y)
    {
        return string.Compare(x.URL.ToString(), y.URL.ToString());
    }

    #endregion
}
nawfal
  • 70,104
  • 56
  • 326
  • 368
Pierluc SS
  • 3,138
  • 7
  • 31
  • 44

2 Answers2

18

You need to override Equals and GetHashCode.

GetHashCode should return the same value for all instances that are considered equal.

For example:

public override bool Equals(object obj) { 
    Href other = obj as Href;
    return other != null && URL.Equals(other.URL);
} 

public override int GetHashCode() { 
    return URL.GetHashCode();
} 

Since .Net's Uri class overrides GetHashCode, you can simply return the URL's hashcode.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
0

You could grab a copy of aku's comparer (beware of the GetHashCode implementation however), and then write something like this

hrefList.Distinct(new Comparer<Href>((h1,h2)=>h1.URL==h2.URL))
Community
  • 1
  • 1
bottlenecked
  • 2,079
  • 2
  • 21
  • 32
  • Yes it does, and that's pretty cool stuff, however, I'm not quite sure how the aku's comparer delegate/readonly is mapping to a method – Pierluc SS Jun 09 '10 at 15:27
  • However, it will work very slowly since all of the hashcodes are the same. – SLaks Jun 09 '10 at 15:42
  • Why when i Dont use h1.URL its not working (even though I override ToString())? – Pierluc SS Jun 09 '10 at 15:48
  • Because you didn't make an `==` operator. – SLaks Jun 09 '10 at 15:49
  • Heh, yeah it works now, weirdly I thought == was mapping to CompareTo by default, but this make sens :) ty ill give you credit. – Pierluc SS Jun 09 '10 at 15:58
  • 2
    No. `==` compares by reference. This `IEqualityComparer` is **wrong** and should not be used. Instead, use [orip's answer](http://stackoverflow.com/questions/98033/wrap-a-delegate-in-an-iequalitycomparer/1239337#1239337), which implements `IEqualityComparer` correctly. (Or just override `GetHashCode` in the `Href` class itself) – SLaks Jun 09 '10 at 16:02