Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to set properties on struct instances using reflection?

I'm trying to write some code that sets a property on a struct (important that it's a property on a struct) and it's failing:

System.Drawing.Rectangle rectangle = new System.Drawing.Rectangle(); PropertyInfo propertyInfo = typeof(System.Drawing.Rectangle).GetProperty("Height"); propertyInfo.SetValue(rectangle, 5, null); 

The Height value (as reported by the debugger) never gets set to anything - it stays at the default value of 0.

I have done plenty of reflection on classes before and this has worked fine. Also, I know that when dealing with structs, you need to use FieldInfo.SetValueDirect if setting a field, but I don't know of an equivalent for PropertyInfo.

like image 446
Victor Chelaru Avatar asked Jun 08 '11 14:06

Victor Chelaru


People also ask

How does reflection set property value?

To set property values via Reflection, you must use the Type. GetProperty() method, then invoke the PropertyInfo. SetValue() method. The default overload that we used accepts the object in which to set the property value, the value itself, and an object array, which in our example is null.

Can structs have properties?

Methods and Properties in StructureA struct can contain properties, auto-implemented properties, methods, etc., same as classes. The following struct includes the static method.


2 Answers

The value of rectangle is being boxed - but then you're losing the boxed value, which is what's being modified. Try this:

Rectangle rectangle = new Rectangle(); PropertyInfo propertyInfo = typeof(Rectangle).GetProperty("Height"); object boxed = rectangle; propertyInfo.SetValue(boxed, 5, null); rectangle = (Rectangle) boxed; 
like image 142
Jon Skeet Avatar answered Sep 28 '22 08:09

Jon Skeet


Ever heard of SetValueDirect? There's a reason they made it. :)

struct MyStruct { public int Field; }  static class Program {     static void Main()     {         var s = new MyStruct();         s.GetType().GetField("Field").SetValueDirect(__makeref(s), 5);         System.Console.WriteLine(s.Field); //Prints 5     } } 

There's other methods than the undocumented __makeref which you could use (see System.TypedReference) but they're more painful.

like image 29
user541686 Avatar answered Sep 28 '22 09:09

user541686