Linq Distinct with a single comparison class (and interface)
I have several classes in my application, all of which have a Name
property that I want to use as m开发者_如何学Pythony 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.
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>());
}
Maybe something like:
var someStuff = GetSomeStuff().Cast<ISomeComparedStuff>().Distinct(new MyComparer);
Or use the non-generic IEqualityComparer
.
精彩评论