8
   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

mustafabar
  • 2,317
  • 6
  • 31
  • 47
  • 1
    see the accepted answer to this question: http://stackoverflow.com/questions/6280506/is-there-a-way-to-set-properties-on-struct-instances-using-reflection – Henrik Jul 07 '11 at 09:29

3 Answers3

13

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();
jbtule
  • 31,383
  • 12
  • 95
  • 128
  • 1
    Thank you. This is the first time I've seen forced boxing (turning a struct into an object) and unboxing (turning the object back into a struct) to see what is happening and understand the process. It is simple, really. But everywhere else I looked, the boxing steps were all done by hidden processes (automatically by the compiler) and it made no sense how one could work with it. – Mark T Jul 30 '15 at 18:28
5

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.

Botz3000
  • 39,020
  • 8
  • 103
  • 127
1

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

DoctorMick
  • 6,703
  • 28
  • 26
  • 2
    +1 Your example shows I think the best that can be done. It isn't possible in "safe" code to alter a field in a genuine value type using reflection, but for every value type there's a corresponding boxed class type. Casting to the ironically-named ValueType will convert a value type into an instance of its corresponding boxed class type, which may then be mutated using reflection; after mutation, the contents of the boxed instance can be copied back to a genuine value-type object. – supercat Jul 26 '11 at 15:09