C# - Value Type Equals method - why does the compiler use reflection?

c#, compiler-construction, struct

Solution

The following is the decompiled ValueType.Equals method 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;
}

When possible, a bit-wise comparison will be done (note the CanCompareBits and FastEqualsCheck, both of which are defined as InternalCall. The JIT would presumably inject the appropriate code here. As to why it is so slow, I couldn't tell you.

Problem

I just came across something pretty weird to me : when you use the Equals() method on a value type (and if this method has not been overriden, of course) you get something very very slow -- fields are compared one to one using reflection ! As in : ``` public struct MyStruct{ int i; } (...) MyStruct s, t; s.i = 0; t.i = 1; if ( s.Equals( t )) /* s.i will be compared to t.i via reflection here. */ (...) ``` My question : why does the C# compiler do not generate a simple method to compare value types ? Something like (in MyStruct's definition) : ``` public override bool Equals( Object o ){ if ( this.i == o.i ) return true; else return false; } ``` The compiler knows what are the fields of MyStruct at compile time, why does it wait until runtime to enumerate MyStruct fields ? Very strange to me. Thanks :) ADDED : Sorry, I just realize that, of course, `Equals` is not a language keyword but a runtime method... The compiler is completely unaware of this method. So it make sens here to use reflection.

Original source