0

Using my code examples why don't the first two objects equal each other when converted to binary?

I know that I could write an override for the equals method and use that to check if two objects are alike. However I was experimenting with this method. Why do two identical objects convert to different binary values?

Given said class:

[Serializable]
public class HashingSample
{
    public int Number { get; set; }

    public HashingSample(int num)
    {
        Number = num;
    }

    public byte[] ToBinary()
    {
        using (MemoryStream stream = new MemoryStream())
        {
            var binaryFormatter = 
                new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            binaryFormatter.Serialize(stream, this);
            return stream.ToArray();
        }
    }
}

And this code:

var s1 = new HashingSample(1).ToBinary();
var s1_2 = new HashingSample(1).ToBinary();
var s2 = new HashingSample(2).ToBinary();

var first2 = s1.Equals(s1_2);
Uwe Keim
  • 39,551
  • 56
  • 175
  • 291
Bailey Miller
  • 1,376
  • 2
  • 20
  • 36

3 Answers3

0

They are equal. Their byte[] are the same length and have the same values.

The .Equals operator does not think so though.

This is probably because the actual instances of s1 and s1_2 are not the same (they are unique instances, so their hashcodes would not be the same.. an s1 is not truly an s1_2 despite having the same byte[] contents.)

CRice
  • 12,279
  • 7
  • 57
  • 84
0

Equals does not do what you expect in the context of arrays - see https://blogs.msdn.microsoft.com/kathykam/2006/03/08/array-equals/ for more details.

Generally speaking, you should assume that Equals does a reference equality check (i.e. checks the two objects are the exact same object, as opposed to two different objects which happen to have the same properties / values in them) - unless the documentation explicitly tells you otherwise.

You could replace:

var first2 = s1.Equals(s1_2);

with:

var first2 = StructuralComparisons.StructuralEqualityComparer.Equals(s1, s1_2);

or

var first2 = s1.SequenceEqual(s1_2);

(or use the code from the link I provided)

mjwills
  • 23,389
  • 6
  • 40
  • 63
0

Possible solution using extensions

public static class HashingExtensions
{
    public static bool Compare(this object v1, object v2)
    {
        var w1 = v1.ToBinary(); var w2 = v2.ToBinary();
        if (w1.Count() == w2.Count())
        {
            for (int x = 0; x < w1.Count(); x++)
            {
                if (w1[x] != w2[x])
                {
                    return false;
                }
            }
            return true;
        }
        else {
            return false;
        }
    }

    public static Byte[] ToBinary(this object obj)
    {
        using (MemoryStream stream = new MemoryStream())
        {
            var binaryFormatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
            binaryFormatter.Serialize(stream, obj);
            return stream.ToArray();

        }
    }
}
Bailey Miller
  • 1,376
  • 2
  • 20
  • 36