Getting value of Value Types in an class using reflection in C#

Advertisements

I wrote the following snippet to illustrate a scenario I faced and can’t come up with the answer to the observed behavior:

public class X
{

    public string XS { get; set; }
    public int XN { get; set; }
    public MyEnum Enum { get; set; }
}

void testValueTypesReflectionComparison()
{
    var x1 = new X { XN = 1, XS = "argh", Enum = MyEnum.Component };
    var x2 = new X { XN = 1, XS = "argh", Enum = MyEnum.Component };

    var xTypeProperties = x1.GetType().GetProperties();
    foreach(var property in xTypeProperties)
    {
        var x1PropertyValue = property.GetValue(x1, null);
        var x2PropertyValue = property.GetValue(x2, null);

        if (x1PropertyValue != x2PropertyValue)
        {
            Console.WriteLine($"different values on property: [{property.Name}]: x1: [{x1PropertyValue}] x2: [{x2PropertyValue}]");
        }
    }
}

Output:

I could not spot anything in the docs that mention particularities in getting value types.
Why are reflected properties XN and Enum values different in x1 and x2 ?

>Solution :

The != operator is … non-trivial. Short version: use object.Equals(x1PropertyValue , x2PropertyValue).

By default, == and != on an object use reference equality comparisons. When you use reflection, you get object instances, and if the underlying value is a value-type, that means "boxing" is in play, which means each box is a separate reference. Two separate boxes of the same value-type value: are not equal under reference equality rules.

This behavior can be overloaded by adding operators for specific types, but that requires knowing the type (or using the new generic operators feature, which is similar to knowing the type).

To use a more flexible (but also more indirect) approach you can use polymorphism on the Equals method, which is what object.Equals(a,b) does, with the advantage that object.Equals(a,b) doesn’t blow up if a is null, but a.Equals(b) does.

Leave a ReplyCancel reply