26

Is there any way to add Field (or FieldInfo, maybe this is the same) to a class at runtime?

Pero P.
  • 25,813
  • 9
  • 61
  • 85
Pavel Podlipensky
  • 8,201
  • 5
  • 42
  • 53
  • possible duplicate of [How do I create dynamic properties in C#?](http://stackoverflow.com/questions/947241/how-do-i-create-dynamic-properties-in-c) – nawfal Jul 20 '14 at 06:36

8 Answers8

28

You can't alter a class definition at runtime. However, you can create a new class that inherits from the original class (if it's not sealed) and declares the field. You can do this by emitting the appropriate IL code using System.Reflection.Emit.

Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
8

No, C# doesn't allow monkey-patching.

You can generate new classes using either CodeDOM or Reflection.Emit, but you can't modify existing ones.

Greg Beech
  • 133,383
  • 43
  • 204
  • 250
7

C# does not allow it because all of it's classes are based on Metadata. The CLR (not C#) disallows the adding of fields to metadata at runtime (1). This is the only way that C# would be able to add a field at runitme.

This is unlike dynamic langauges such as IronPython which essentially don't have concrete metadata classes. They have more dynamic structures which can be altereted at runtime. I believe IronPython simply keeps it's members (fields and methods) in what amounts to a hashtable that can be easily altered at runtime.

In C# 3.0, your best resource is to use Reflection.Emit. But this will generate an entirely new class vs. altering an existing one.

(1) There are certain APIs such as the profiling APIs or ENC that allow this but I'm not sure if their capabalities expand to adding fields.

JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
2

See this question for a simple way to do it in C# 4.0, by casting an ExpandoObject as an IDictionary, which causes the values added to the dictionary to become properties of the object. I demonstrate this in another answer of mine showing that they actually become properties.

However, this is only possible with an instance of ExpandoObject or by sub-classing DynamicObject.

It may also be possible to use with other classes if they implement IDynamicMetaObjectProvider, but I think there is too much work involved to get it to work properly.

Community
  • 1
  • 1
yoel halb
  • 12,188
  • 3
  • 57
  • 52
1

Not exactly.

However, you can implement ICustomTypeDescriptor to approximate it, and then just use a hashtable to store the fieldname/value pairs. A lot of the framework which uses reflection asks for ICustomTypeDescriptor first.

codekaizen
  • 26,990
  • 7
  • 84
  • 140
  • Thanks, I've tried this approach, but it doesnt work for me. I'm trying to impelment IExpando interface to allow javascript code calls unexisted fields in my C# class. For example, var o = new ActiveXObject('mCom'); o.ArbitraryField = "Foo"; Please note that ArbitraryField doesnt exists at my class. – Pavel Podlipensky Mar 15 '09 at 09:35
  • Have you just tried implementing IReflect? It's the way to implement IDispatch/IExpando for interop with dynamic languages (at least before C# 4.0). http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.aspx I've done this exact thing with a hashtable implementation and it works well – codekaizen Mar 15 '09 at 15:06
1

Not until C# 4.0 which adds dynamic lookup and is based on the CLR 4.0 which incorporates the DLR, and then it will not strictly be adding to a class, as classes won't be in the picture.

Daniel Earwicker
  • 114,894
  • 38
  • 205
  • 284
  • I wouldn't think this will be possible in C# 4.0. I think that you won't be able to alter existing types. However, I can imagine that you could create some dynamic object (e.g. coming from Ruby) and than alter it. – Tomas Petricek Mar 14 '09 at 17:59
  • That's what I meant by "not strictly be adding to a class, as classes won't be in the picture". Rather, individual objects referenced by 'dynamic' will be able to accept assignment to a property that didn't previous exist, and deal with this by dynamically adding a property. – Daniel Earwicker Mar 14 '09 at 19:08
1

as others already said, this isn't possible. What is the reason for your question? If you need to store some additional data in the class dynamically, then you could probably just use dictionary:

class My { 
   Dictionary<string, object> data;
   public My() { data = new Dictionary<string, object>(); }
}

.. but it really depends on what you actually want to achieve?

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • My aim is to implement IExpando interface. My super aim is to allow javascript code to add fields to ActiveX object dynamically and in "javascript way". For example, var myobj = new ActiveXObject('server.object'); myobj.ArbitraryField = "something"; Please note taht ArbirtaryField doesnt exists – Pavel Podlipensky Mar 15 '09 at 09:33
0

Perhaps you could use the Decorator pattern.

In object-oriented programming, the decorator pattern is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.

http://www.dofactory.com/Patterns/PatternDecorator.aspx

ChatGPT
  • 5,334
  • 12
  • 50
  • 69