Как использовать пользовательский компаратор для EqualityComparer <T>.Default? - PullRequest
0 голосов
/ 26 марта 2019

Примечание: мой случай для байта [], но я считаю, что хороший ответ будет работать для любого типа.

Автоматически сгенерированная реализация Visual Studio Equals использует EqualityComparer<T>.Default.Equals(T x, T y) для ссылочных типов. У меня есть много классов с байтовыми массивами, которые необходимо включить в Equals, поэтому я хотел бы сохранить код Visual Studio, если это возможно, но Default возвращает ObjectEqualityComparer для байтовых массивов. Я написал простой компаратор байтового массива, но я не уверен, как его использовать вместо ObjectEqualityComparer.

public class Foo
{
    public int Id {get;set;}
    public byte[] Data {get;set;}

    public override bool Equals(object obj)
    {
        var foo = obj as Foo;
        return foo != null &&
            Id == foo.Id &&
            EqualityComparer<byte[]>.Default.Equals(Data, foo.Data);
    }
}

static void Main
{
    Foo f1 = new Foo { Id = 1, Data = new byte[1] { 0xFF } };
    Foo f2 = new Foo { Id = 1, Data = new byte[1] { 0xFF } };
    bool result = f1.Equals(f2); // false
}

public class ByteArrayComparer
{
    public bool Equals(byte[] x, byte[] y)
    {
        return x.SequenceEqual(y);
    }

    public int GetHashCode(byte[] obj)
    {
        return obj.GetHashCode(); 
        // as Servy said, this is wrong but it's not the point of the question, 
        // assume some working implementation
    }
}

Должен ли ByteArrayComparer реализовать IEqualityComparer, наследовать от EqualityComparer и переопределить методы или что-то еще?

1 Ответ

1 голос
/ 26 марта 2019

Создайте и используйте экземпляр своего пользовательского компаратора вместо использования EqualityComparer<byte[]>.Default в своем классе:

public class Foo
{
    public int Id { get; set; }
    public byte[] Data { get; set; }

    private readonly ByteArrayComparer _comparer = new ByteArrayComparer();

    public override bool Equals(object obj)
    {
        var foo = obj as Foo;
        return foo != null &&
            Id == foo.Id &&
            _comparer.Equals(Data, foo.Data);
    }
}

Вы также можете реализовать IEqualityComparer<T> и GetHashCode()в вашем ByteArrayComparer классе.EqualityComparer<T>.Default возвращает экземпляр класса, который реализует этот интерфейс, но я предполагаю, что вы не хотите использовать его, поскольку вы реализовали свой собственный пользовательский компаратор.

Как использовать IEqualityComparer

...