Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't reflection set a property in a Struct?

   class PriceClass {

        private int value;
        public int Value
        {
            get { return this.value; }
            set { this.value = value; }
        }           
    }


    struct PriceStruct
    {

        private int value;
        public int Value
        {
            get { return this.value; }
            set { this.value = value; }
        }
    }
    static void Main(string[] args)
    {
        PriceClass _priceClass = new PriceClass();
        Type type = typeof(PriceClass);
        PropertyInfo info = type.GetProperty("Value");
        info.SetValue(_priceClass, 32, null);
        Console.WriteLine(_priceClass.Value);

        PriceStruct _priceStruct = new PriceStruct();
        type = typeof(PriceStruct);
        info = type.GetProperty("Value");
        info.SetValue(_priceStruct, 32, null);
        Console.WriteLine(_priceStruct.Value);

        Debugger.Break();
    }

The first value printed is 32 while the second is 0. No exception thrown

like image 233
mustafabar Avatar asked Jul 07 '11 09:07

mustafabar


3 Answers

It's because boxing your struct makes a copy of it, so you should box it earlier so you call the getter from the same data that you modified. The following code works:

    object _priceStruct = new PriceStruct(); //Box first
    type = typeof(PriceStruct);
    info = type.GetProperty("Value");
    info.SetValue(_priceStruct, 32, null);
    Console.WriteLine(((PriceStruct)_priceStruct).Value); //now unbox and get value

    Debugger.Break();
like image 175
jbtule Avatar answered Sep 28 '22 08:09

jbtule


structs are ValueTypes, which are passed by value, that means you only pass around copies of the entire struct, not a reference to the original object.

So when you pass it into info.SetValue(_priceStruct, 32, null), a copy is passed to the method and mutated, so the original object doesn't get changed at all. Another reason why mutable structs are evil.

like image 43
Botz3000 Avatar answered Sep 28 '22 07:09

Botz3000


You can still change them using reflection but it is a bit long winded.

See this example: http://social.msdn.microsoft.com/Forums/en/netfxbcl/thread/2dd4315c-0d0d-405c-8d52-b4b176997472

like image 42
DoctorMick Avatar answered Sep 28 '22 07:09

DoctorMick