【问题标题】:How to use a custom comparer for EqualityComparer<T>.Default?如何为 EqualityComparer<T>.Default 使用自定义比较器?
【发布时间】:2019-03-27 22:50:25
【问题描述】:

注意:我的情况是 byte[] 但我相信一个好的答案适用于任何类型。

Visual Studio 自动生成的Equals 实现使用EqualityComparer&lt;T&gt;.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 继承并覆盖方法,还是其他?

【问题讨论】:

  • 无论您写什么,都无法让EqualityComparer&lt;byte[]&gt;.Default 返回任何其他内容。如果可以的话,这将是一个全球性的问题——谁的“byte[] 的全局默认相等比较器”是正确的?自定义 type 可以实现 IEquatable,但对于现有系统类型,您无法分配新的“更明智”的默认值。您能做的最好的事情就是创建新的比较器,并明确地使用它们。
  • 您的比较器不会为“相等”数组返回相同的哈希码,因此它甚至不起作用。感谢您无法将其设为默认比较器。
  • @JeroenMostert 对,我认为这是不可能的。
  • 至少它应该实现IEqualityComparer&lt;byte[]&gt; 来使用它,例如在 linq 方法中,但您将无法让 EqualityComparer&lt;byte[]&gt;.Default 返回您的类的实例。
  • @Servy:谢谢,你雄辩地阐述了我在“正确”周围引用的目的。

标签: c# iequalitycomparer


【解决方案1】:

创建并使用您的自定义比较器的实例,而不是在您的班级中使用 EqualityComparer&lt;byte[]&gt;.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);
    }
}

您可能还想在您的ByteArrayComparer 类中实现IEqualityComparer&lt;T&gt;GetHashCode()EqualityComparer&lt;T&gt;.Default 返回一个实现此接口的类的实例,但我假设您不想使用这个,因为您已经实现了自己的自定义比较器。

How to use the IEqualityComparer

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 1970-01-01
    • 1970-01-01
    • 2019-05-13
    相关资源
    最近更新 更多