Перенесите делегата в IEqualityComparer

125
задан Marcelo Cantos 15 September 2010 в 22:03
поделиться

6 ответов

Я боюсь, что из поля нет такой обертки. Однако не трудно создать то:

class Comparer<T>: IEqualityComparer<T>
{
    private readonly Func<T, T, bool> _comparer;

    public Comparer(Func<T, T, bool> comparer)
    {
        if (comparer == null)
            throw new ArgumentNullException("comparer");

        _comparer = comparer;
    }

    public bool Equals(T x, T y)
    {
        return _comparer(x, y);
    }

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

...

Func<int, int, bool> f = (x, y) => x == y;
var comparer = new Comparer<int>(f);
Console.WriteLine(comparer.Equals(1, 1));
Console.WriteLine(comparer.Equals(1, 2));
48
ответ дан 24 November 2019 в 00:55
поделиться

Я собираюсь ответить на свой собственный вопрос. Для обработки Словарей как наборов самый простой метод, кажется, для применения операций присвоения к dict. Ключи, затем преобразуйте назад в Словари со Счетным. ToDictionary (...).

2
ответ дан 24 November 2019 в 00:55
поделиться
public class FuncEqualityComparer<T> : IEqualityComparer<T>
{
    readonly Func<T, T, bool> _comparer;
    readonly Func<T, int> _hash;

    public FuncEqualityComparer( Func<T, T, bool> comparer )
        : this( comparer, t => t.GetHashCode())
    {
    }

    public FuncEqualityComparer( Func<T, T, bool> comparer, Func<T, int> hash )
    {
        _comparer = comparer;
        _hash = hash;
    }

    public bool Equals( T x, T y )
    {
        return _comparer( x, y );
    }

    public int GetHashCode( T obj )
    {
        return _hash( obj );
    }
}

С расширениями:-

public static class SequenceExtensions
{
    public static bool SequenceEqual<T>( this IEnumerable<T> first, IEnumerable<T> second, Func<T, T, bool> comparer )
    {
        return first.SequenceEqual( second, new FuncEqualityComparer<T>( comparer ) );
    }

    public static bool SequenceEqual<T>( this IEnumerable<T> first, IEnumerable<T> second, Func<T, T, bool> comparer, Func<T, int> hash )
    {
        return first.SequenceEqual( second, new FuncEqualityComparer<T>( comparer, hash ) );
    }
}
11
ответ дан 24 November 2019 в 00:55
поделиться

Если вы хотите настроить проверку равенства, в 99% случаев вы заинтересованы в определении ключей для сравнения, а не в самом сравнении.

Это может быть элегантное решение (концепция из списка Python метод sort ).

Использование:

var foo = new List<string> { "abc", "de", "DE" };

// case-insensitive distinct
var distinct = foo.Distinct(new KeyEqualityComparer<string>( x => x.ToLower() ) );

Класс KeyEqualityComparer :

public class KeyEqualityComparer<T> : IEqualityComparer<T>
{
    private readonly Func<T, object> keyExtractor;

    public KeyEqualityComparer(Func<T,object> keyExtractor)
    {
        this.keyExtractor = keyExtractor;
    }

    public bool Equals(T x, T y)
    {
        return this.keyExtractor(x).Equals(this.keyExtractor(y));
    }

    public int GetHashCode(T obj)
    {
        return this.keyExtractor(obj).GetHashCode();
    }
}
118
ответ дан 24 November 2019 в 00:55
поделиться

Я не знаю о существующем классе, но чем-то как:

public class MyComparer<T> : IEqualityComparer<T>
{
  private Func<T, T, bool> _compare;
  MyComparer(Func<T, T, bool> compare)
  {
    _compare = compare;
  }

  public bool Equals(T x, Ty)
  {
    return _compare(x, y);
  }

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

Примечание: Я на самом деле не скомпилировал и выполнил это все же, таким образом, могла бы быть опечатка или другая ошибка.

-2
ответ дан 24 November 2019 в 00:55
поделиться

Всего одна оптимизация: Мы можем использовать готовый EqualityComparer для сравнения значений, а не делегировать его.

Это также сделало бы реализацию более чистой, поскольку фактическая логика сравнения теперь остается в GetHashCode () и Equals (), которые вы, возможно, уже перегрузили.

Вот код:

public class MyComparer<T> : IEqualityComparer<T> 
{ 
  public bool Equals(T x, T y) 
  { 
    return EqualityComparer<T>.Default.Equals(x, y); 
  } 

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

Не забудьте перегрузить методы GetHashCode () и Equals () на вашем объекте.

Мне помог этот пост: c # сравнить два общих значения

Sushil

1
ответ дан 24 November 2019 в 00:55
поделиться
Другие вопросы по тегам:

Похожие вопросы: