简体   繁体   English

具有数组属性的类的 C# 相等

[英]C# Equality for classes having array properties

I have following value我有以下价值

public class Identification : IEquatable<Identification> 
{
    public int Id { get; set; }
    public byte[] FileContent { get; set; }
    public int ProjectId { get; set; }
}

Which I generated equality members for with resharper我用 resharper 生成了平等成员

    public bool Equals(Identification other)
    {
        if (ReferenceEquals(null, other)) return false;
        if (ReferenceEquals(this, other)) return true;
        return Id == other.Id && Equals(FileContent, other.FileContent) && ProjectId == other.ProjectId;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        if (ReferenceEquals(this, obj)) return true;
        if (obj.GetType() != this.GetType()) return false;
        return Equals((Identification) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            var hashCode = Id;
            hashCode = (hashCode*397) ^ (FileContent != null ? FileContent.GetHashCode() : 0);
            hashCode = (hashCode*397) ^ ProjectId;
            return hashCode;
        }
    }

    public static bool operator ==(Identification left, Identification right)
    {
        return Equals(left, right);
    }

    public static bool operator !=(Identification left, Identification right)
    {
        return !Equals(left, right);
    }

But when I want to unit test it's equality before and after returning from the repository it fails.但是当我想对它从存储库返回之前和之后的相等性进行单元测试时,它失败了。 Despite having the exact same properties in the failure message.尽管在失败消息中具有完全相同的属性。

var identification = fixture
                .Build<Identification>()
                .With(x => x.ProjectId, projet.Id)
                .Create();
await repository.CreateIdentification(identification);
var returned = await repository.GetIdentification(identification.Id);

Assert.Equal() Failure Assert.Equal() 失败

Expected: Identification { FileContent = [56, 192, 243], Id = 8, ProjectId = 42 }预期:标识 { FileContent = [56, 192, 243], Id = 8, ProjectId = 42 }

Actual: Identification { FileContent = [56, 192, 243], Id = 8, ProjectId = 42 }实际:标识 { FileContent = [56, 192, 243], Id = 8, ProjectId = 42 }

I'm using Npgsql with Dapper if it matters.如果重要的话,我将 Npgsql 与 Dapper 一起使用。

You should use Enumerable.SequenceEqual for arrays which checks for:您应该将Enumerable.SequenceEqual用于检查以下各项的数组:

  • Both arrays are null or both arrays are not null .两个数组都为null或两个数组都不为null
  • Both arrays have same Length .两个数组具有相同的Length
  • Corresponging items are equal to one another.对应项彼此相等。

Something like this像这样的东西

public bool Equals(Identification other)
{
    if (ReferenceEquals(null, other)) 
      return false;
    else if (ReferenceEquals(this, other)) 
      return true;

    return Id == other.Id && 
           ProjectId == other.ProjectId &&
           Enumerable.SequenceEqual(FileContent, other.FileContent);
}

Since Enumerable.SequenceEqual can well be time cosuming I've shifted it to the end of the comparison (there's no need to check arrays if, say, ProjectId are failed to be equal)由于Enumerable.SequenceEqual可能很耗时,我已经将它移到比较的末尾(如果ProjectId不相等,则无需检查数组)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM