views:

45

answers:

2

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
    }
+2  A: 

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
i am not quite sure why we are overriding a method of the interface
Burnzy
@Burnzy: There is no interface involved here. These methods are inherited from `Object`.
SLaks
A: 

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))
bottlenecked
This will not work. (`Distinct` _requires_ `GetHashCode`)
SLaks
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
Burnzy
However, it will work very slowly since all of the hashcodes are the same.
SLaks
Why when i Dont use h1.URL its not working (even though I override ToString())?
Burnzy
Because you didn't make an `==` operator.
SLaks
Heh, yeah it works now, weirdly I thought == was mapping to CompareTo by default, but this make sens :)ty ill give you credit.
Burnzy
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<T>` correctly. (Or just override `GetHashCode` in the `Href` class itself)
SLaks