17

I have a class :

class MyClass 
{
}
...
MyClass c = new MyClass();

Is it possible to add properties / fields to this class on run-time ?

(I don't know what are their types or names on compile-time and they don't have a common interface which I can use.)

psuedo example :

 Add property named "Prop1" [type System.Int32]
 Add property named "Prop900" [type System.String]

I already read this question but it uses interface

Thanks in advance.

Community
  • 1
  • 1
Royi Namir
  • 144,742
  • 138
  • 468
  • 792

3 Answers3

48

You cannot extend an existing class with new members at runtime. However, you can create a new class using System.Reflection.Emit that has the existing class as base class.

typeBuilder.SetParent(typeof(MyClass));
typeBuilder.DefineProperty("Prop1", ..., typeof(System.Int32), null);
...

See TypeBuilder.DefineProperty Method (String, PropertyAttributes, Type, Type[]) for a full example.

dtb
  • 213,145
  • 36
  • 401
  • 431
6

I think you have misunderstood what reflection is. Reflection does not allow you to change the code you are running. It can allow you to read your own code and even run that code.

With Reflection.Emit you can write a whole new assembly and then have it loaded into memory.

However you CANNOT change a class at runtime. Imagine, you have a class Foo, you instanciate a whole bunch of them, then decide to change the class.

What should happen to all the Foos you already instanciated?

However, what you CAN do it use Reflection.Emit to create a new class that inherits Foo, called Bar, and then add whatever you need to that class.

Alternatively if you want to programmatically add a property to a class AFTER compile time but BEFORE run time, you can look at IL Weaving/AOP. I suggest looking at PostSharp or Fody if this is what you are interested in.

Simon
  • 33,714
  • 21
  • 133
  • 202
Aron
  • 15,464
  • 3
  • 31
  • 64
2

Yes, you can use the ExpandoObject class to achieve this.

dynamic expando = new ExpandoObject();
expando.Prop1 = 10;
expando.Prop900 = string.Empty;
Daniel Hilgarth
  • 171,043
  • 40
  • 335
  • 443