0

How does default Equals() work on struct like this one:

public struct Decim
{
    decimal x;

    public Decim (decimal x)
    {
        this.x = x;
    }
}

new Decim(-0m).Equals (new Decim(0m)); return true, why? if it doing bitwise comparsion, I thought decimal uses special bit to indicate sign

also new Decim(5.00m).Equals (new Decim(5.000000m)); reports true, but when I do new Decim(5.00m).ToString() and new Decim(5.000000m)).ToString() it produces different values. How does to string knows it?

apocalypse
  • 5,764
  • 9
  • 47
  • 95

2 Answers2

0

This is the decompiled version of Equals from mscorlib:

public override bool Equals(object obj)
{
    if (obj == null)
    {
        return false;
    }
    RuntimeType type = (RuntimeType) base.GetType();
    RuntimeType type2 = (RuntimeType) obj.GetType();
    if (type2 != type)
    {
        return false;
    }
    object a = this;
    if (CanCompareBits(this))
    {
        return FastEqualsCheck(a, obj);
    }
    FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
    for (int i = 0; i < fields.Length; i++)
    {
        object obj3 = ((RtFieldInfo) fields[i]).InternalGetValue(a, false);
        object obj4 = ((RtFieldInfo) fields[i]).InternalGetValue(obj, false);
        if (obj3 == null)
        {
            if (obj4 != null)
            {
                return false;
            }
        }
        else if (!obj3.Equals(obj4))
        {
            return false;
        }
    }
    return true;
}

You can understand what the Equals does.

source: Original StackOverflow post

Community
  • 1
  • 1
Stefano Bafaro
  • 915
  • 10
  • 20
  • So, why I does not enter CanCompareBits for decimal, but when I change field to double, it enters? How Does CanCompareBits work? Cannot see, because its extern. – apocalypse Mar 30 '15 at 12:20
0

Found it: Can anyone explain this strange behavior with signed floats in C#?

In default Equals:

if (CanCompareBits(this)) // will return false for decimal
{
    return FastEqualsCheck(a, obj);
}

So defauklt equals will use reflection for decimal field. For double it will do fastEqualsCheck.

Community
  • 1
  • 1
apocalypse
  • 5,764
  • 9
  • 47
  • 95