How can I dynamically add a field to a class in C# - c#

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

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.

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.

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.

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.

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.

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.

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?

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

Related

C# Serialization limitations

i want to implement a general Memento-Pattern in C#. It is working fine but i use the Serializeable() Attribute to do a deep copy of a object. My implementation using generics so if someone use it he has to give his class as type.
Now the class from user must have the Attribute Serializeable() too. Are there any limitations for a class which using Serializeable()?
In fact:
Are there any performance problems?
Is it possible to use an interface?
Is it possible to use inerhitence?
Is it possible to use Auto-Properties?
I dont know how the Attribute works and so iam a bit scary of using this in such a global way.
regards
for small models that you are cloning in memory, not usually
irrelevent; when using [Serializable] you are typically using BinaryFormatter - which looks at the objects themselves; it doesn't matter what interfaces they implement - the interfaces are not used
yes, for the same reason - but all types in the model must be [Serializable]
yes, for the same reason; note : the default BinaryFormatter implementation is looking at fields - it won't even touch the properties
Personally, I try to advise against BinaryFormatter, but this is perhaps not an unreasonable use. However! Be careful that it is easy to suck extra objects into the model accidentally, must commonly through events. Note that it is a good idea to mark all events as non-serialized:
[field:NonSerialized]
public event EventHandler Something;
(or apply to the field directly if using explicit add/remove accessors)
Note also that any members like:
public object Tag {get;set;} // caller-defined
should also probably be [field:NonSerialized].
Personally, I'd prefer a different serializer, but: this will often work. I will say, though: try to avoid persisting the output of BinaryFormatter, as it is hard to guarantee compatibility between revisions of your code.
I dont know how the Attribute works
It does nothing at all except add an IL flag that says "by the way, consider this ok to be serialized"; actually, most serializers don't even look at this flag - but BinaryFormatter is one of the few that do look at this flag. The real code here is BinaryFormatter, which basically does:
have I seen this object before? if so, store the key only
what type is it? is it [Serializable]? store the type info
invent a new reference and store that as the identity
does it have a custom serializer? if so: use that
what fields does it have? access each in turn and store the name/value pair

Interface vs internal variable vs inheritance dictionary

I have read
When should I choose inheritance over an interface when designing C# class libraries?
I believe I understand is-a vs must-do relationship. Having said all that here is my dilemma.
I want to implement a Collection of key value pairs most likely object. I need to add to the add and remove events only to do validation, check for duplication and some tracking stuff.
If I implement IDictionary it seems that it is a bit of an over kill to implement all the Idictionary<>, ICollection<>, IEnumerable<>, and IEnumerable. Yes most of them are one liners.
It is not recommended to inherit from Dictionary as it was never meant to be extended, shadowing the Add and remove.
Finally I can just implement a private variable and then expose the methods I want or need for the project
Any suggestions on the direction to go?
You should use composition and encapsulate a dictionary inside your class (the private variable option). This way, you only expose to the outside world the operations that make sense for your object and the fact that you use a dictionary is a mere implementation detail.
You should only implement IDictionary<,> or inherit from Dictionary<,> if your class is a generic dictionary with some special characterists.
The simplest approach would be to implement the IDictionary as an instance variable and wrap the Add and Remove methods in Add and Remove methods in your class that perform validation before adding or removing the object to or from the dictionary.
Inheritance is for when you need to inherit implementation. Otherwise, if you want to inherit interface, bit not implementation, uses interfaces.
I would suggest perhaps designing some of your own dictionary-ish interfaces which include the functionality you're interested in. Among other things, I would suggest having some interfaces which exist purely for reading the interface, and some which allow read-write access. Among other things, if you have a read-only interface, methods which don't care whether a particular dictionary is mutable or immutable will be able to use an IReadableDict (implemented by both mutable and immutable dictionaries) while routines that require either that a dictionary be mutable or that it be immutable will be able to specify that. Further, segregating out some other interfaces will allow maximum possibilities for covariance and contravariance. For example, code which is expecting an IReadableDict<String, Animal> could be perfectly happy with a Dict<String, Cat> even though code which was expecting an IReadWriteDict<String, Animal> would not be able to accept an Dict<String, Cat>. Likewise, code which only needs to know the count of a dictionary could accept a non-generic ICountable which exposes a Count method, and code which only needs to know whether a certain key exists could accept a non-generic IQueryExistence (note that one can perfectly legitimately check whether a Dict<Cat, PurrVolume> contains a particular instance of Dog; the answer will be 'no', but the question is valid).

How to add properties to the object at run-time in .net?

I'm using a 3rd party lib to do some work. I'm passing an object to the lib and it performing some actions on each property of the object. It enumerates properties using reflection. This is how it implemented and I can't change it.
I don't know which and how many properties should be processed by the lib at compile-time. This information only available at run-time. So I can't create class declaration in my source code.
It seems dynamic feature of .net4 can't help me because lib using reflection, not dynamic.
Actually I can see only two options here:
Create a huge class definition like this:
class Data
{
public object P1 {get; set;}
public object P2 {get; set;}
....
public object PN {get; set;} // N should be at least 10.000
}
Generate class definition at runtime and use CSharpCodeProvider to compile an use it.
Can you suggest me any other options?
And sadly, I can't replace this lib with another one.
Using the first approach will lead to high memory consumption. I would have chosen use TypeBuilder class to create new types at the runtime.
What you're looking for is known as a Property Bag. You may be able to implement something like this by using ICustomTypeDescriptor to expose additional metadata (assuming your library supports it).
If your consuming library is using Reflection directly (and not taking advantage of designer features like Type Descriptors) then your best bet is probably dynamic generation of a proxy wrapper with the additional properties. Castle DynamicProxy is one good way to do this.
EDIT:
Actually, I'm not sure if Castle supports adding new properties to the proxy object. You might be stuck using IL Emit directly via TypeBuilder. This is non-trivial, as you'll need to learn enough about IL Emit to generate the property accessors and there's a bit of a learning curve. That said, it's interesting and fun stuff and worth the effort if you have the time.
I guess it's about regular GUI element like Grid or PropertyGrid.
Then I would start from reflecting grid's method that accept class instance as parameter, and if it is possible fill internal Dictionary<PropertyInfo, instance> or Dictionary<Name,Value> with my own vales.
If this is impossible, instead of Emit, try to use System.CodeDom:
Link

How to change class definition on runtime?

Is there a way for me to change the properties a class has (add/remove properties) on runtime?
You cannot do this unless you are working with an instance of ExpandoObject. The metadata for a CLR type is fixed in the assembly and cannot be changed at execution time. If you really need this kind of dynamic behavior you must use a dynamic type (like EpandoObject) that supports this behavior.
Just to add to Andrew Hare's reply: With C# 4 and .NET 4 you can inherit from DynamicObject and redefine what it means to take various actions on an instance of the type. DynamicObject defines a number of virtual methods that you can override to take control of what it means to e.g. access a property. You could use this to allow properties to be added/removed to the instance, which is pretty much what ExpandoObject does.
For more about ExpandoObject see this question and this blog post.
You could create your types at runtime using System.Reflection.Emit -link
For UI development (i.e. what is presented to the end user) look at implementing ICustomTypeDescriptor (in System.ComponentModel). Many controls are aware of this interface and will use it to query the properties an instance or type exposes.
If you are on 3.5 you can use IL to create a dynamic type, and also accomplish the task, but it's a lot harder, but there are some frameworks for doing that I suppose.

C# 4.0: Why MethodBag when there's ExpandoObject?

I don't understand, why use dynamic MethodBags when I can use ExpandoObject? What am I missing here?
MethodBags and analogous implementations tend to have some limitations. It may be easier just to implement your own class if you find yourself running into these roadblocks. Specifically:
Hard to implement state in a method bag. (Expression trees cannot contain objects that are statically typed as dynamic; no good syntax to create methods that rely on internal state on the same dynamic object.)
Can only add public methods. No virtual, private, protected, or abstract methods.
Can't implement an interface.
In comparison, ExpandoObjects are true classes and are much richer and more full-featured. They more closely mimic what you'd otherwise get for free in, say, Ruby or Python.
Quick note: for those who don't know, dynamic method bag is a technique for adding methods dynamically to an object. Bill Wagner describes it here with source code here.
The simple answer is that the MethodBag concept is just showing you a technique. You can absolutely use the ExpandoObject to do this, but there may be a time when you want to write your own class that inherits from System.Dynamic.DynamicObject. An example of this might be to provide a dynamic JSON, YAML, or XML object that lets you reference your data in dot-properties-notation rather than in the traditional stringy ways. If you inherit from DynamicObject, you may find that you want to allow the addition of dynamic functions to your class too. The MethodBag technique shows you how to do that. The ExpandoObject is just one example of a class that implements this technique. ExpandoObject will be good for 95% of what you need, and the MethodBag technique shows you how to custom write your own when you decide to do that for the last 5%.

Categories

Resources