简体   繁体   中英

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

    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

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

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

I'm using Npgsql with Dapper if it matters.

You should use Enumerable.SequenceEqual for arrays which checks for:

  • Both arrays are null or both arrays are not null .
  • Both arrays have same 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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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