Question

I have several classes in my application, all of which have a Name property that I want to use as my basis for comparison (Distinct(), etc.). Since I am always going to be comparing on Name, I decided to extract an interface, ISomeComparedStuff, which simply has a Name propery that all my other classes implement. I set up a comparison class as such:

public class MyComparer : IEqualityComparer<ISomeComparedStuff>
{
     public bool Equals(ISomeComparedStuff x, ISomeComparedStuff y)
     {
          return x.Name == y.Name;
     }

     public int GetHashCode(ISomeComparedStuff obj)
     {
          return obj.Name.GetHashCode();
     }
}

The only problem is when I try to code against it:

public class SomeStuff : ISomeComparedStuff
{
  ...
}

public class SomeMoreStuff : ISomeComparedStuff
{
  ...
}

var someStuff = GetSomeStuff().Distinct(new MyComparer);
var someMoreStuff = GetSomeMoreStuff().Distinct(new MyComparer);

I am getting a cast error (SomeStuff to ISomeComparedStuff). Is there some way to do this so I only need one compare class, otherwise I'd have to create one for every one of my classes (even though I am always going to compare on Name)?

Note: I understand this question "title" needs help. Any suggestions would be great.

Was it helpful?

Solution

Not sure if this is a good solution or not, but how about making MyComparer a generic class?

public class MyComparer<T> : IEqualityComparer<T>
    where T: ISomeComparedStuff
{
     public bool Equals(T x, T y)
     {
      return x.Name == y.Name;
     }

     public int GetHashCode(T obj)
     {
      return obj.Name.GetHashCode();
     }
}

Downside is you have to new up an appropriate version:

var someStuff = GetSomeStuff().Distinct(new MyComparer<SomeStuff>());
var someMoreStuff = GetSomeMoreStuff().Distinct(new MyComparer<SomeMoreStuff>());

Expanding a bit, you could also make a new extension method like this:

public static IEnumerable<T> DistinctByName<T>(this IEnumerable<T> values)
    where T: ISomeComparedStuff
{
    return values.Distinct(new MyComparer<T>());
}

OTHER TIPS

Maybe something like:

var someStuff = GetSomeStuff().Cast<ISomeComparedStuff>().Distinct(new MyComparer);

Or use the non-generic IEqualityComparer.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top