tags:

views:

2101

answers:

6

Hi,

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

Thanks, Paul.

+2  A: 

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
It's called monkey-patching? Where did that term originate?
Tor Haugen
No idea where it comes from, but I've added a link to the Wikipedia entry.
Greg Beech
+7  A: 

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
A: 

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
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.
Paul Podlipensky
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.aspxI've done this exact thing with a hashtable implementation and it works well
codekaizen
A: 

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
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
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
+1  A: 

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
A: 

Hi, 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
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
Paul Podlipensky