Linq Distinct с одним классом сравнения (и интерфейсом) - PullRequest
2 голосов
/ 30 декабря 2010

В моем приложении есть несколько классов, каждый из которых имеет свойство Name, которое я хочу использовать в качестве основы для сравнения (Distinct() и т. Д.). Поскольку я всегда собираюсь сравнивать Name, я решил извлечь интерфейс ISomeComparedStuff, который просто обладает свойством Name, которое реализуют все мои другие классы. Я настроил класс сравнения так:

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();
     }
}

Единственная проблема, когда я пытаюсь код против нее:

public class SomeStuff : ISomeComparedStuff
{
  ...
}

public class SomeMoreStuff : ISomeComparedStuff
{
  ...
}

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

Я получаю ошибку приведения (SomeStuff к ISomeComparedStuff). Есть ли какой-нибудь способ сделать это, поэтому мне нужен только один класс сравнения, в противном случае мне пришлось бы создавать его для каждого из моих классов (хотя я всегда собираюсь сравнивать на Name)?

Примечание: я понимаю, что этот вопрос "название" нуждается в помощи. Любые предложения будут великолепны.

Ответы [ 2 ]

2 голосов
/ 30 декабря 2010

Не уверен, что это хорошее решение или нет, но как насчет того, чтобы сделать MyComparer универсальным классом?

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();
     }
}

Недостатком является необходимость обновления соответствующей версии:

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

Немного расширив, вы также можете создать новый метод расширения, подобный этому:

public static IEnumerable<T> DistinctByName<T>(this IEnumerable<T> values)
    where T: ISomeComparedStuff
{
    return values.Distinct(new MyComparer<T>());
}
0 голосов
/ 30 декабря 2010

Может быть что-то вроде:

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

Или используйте неуниверсальный IEqualityComparer.

...