views:

57

answers:

3

I am exploring the DynamicObject model in .NET 4.0. The application is one where an object will be described through some sort of text/xml file, and the program must create an object upon reading that file.

With DynamicObject, we can add members easily, given that we know the name of the member a priori. But, what if we don't even know the name of the member to add? Is there a way to make that dynamic as well?

For example, say I need to create an object with members 'Property1', 'Property2', and another object with 'PropertyA', and 'PropertyB' as described by the text/XML file. How can I create an object dynamically based on this info?

UPDATE I got some ideas from this post: http://www.codeproject.com/KB/cs/dynamicincsharp.aspx

This implementation allows me to do something like the following:

dynamic d = new PFDynamicChannel();
PFCouplings c = ((PFChannel)d).Coupling;
d.NewProperty = "X";

The reason I do not wish to use a dictionary is to make use of TryGetMember, and TrySetMember methods that I can override, within which I can raise events that are essential for the program.

This way, I can inherit from a base class (PFChannel), but I can also add members on the fly. But, my problem is that I will not know the new property name until runtime. And, I actually don't think the dynamic object allows me to add new properties on the fly. If this is the case, how can I make use of ExpandoObject to give me this ability?

+2  A: 

If you only need to do that, you should look at ExpandoObject. If you need to do that and still use DynamicObject, you will need to write code to remember property values, basically... which you could potentially do with an embedded ExpandoObject.

It's not clear to me what you want to do with this object afterwards though - are you sure you need dynamic typing at all? Would a Dictionary<string, object> actually be any worse? It depends what's going to consume the object later basically.

Jon Skeet
Well, the object actually needs to inherit a baseclass. The baseclass defines numerous events and properties that are essential to the rest of the program. One reason why I am interested in DynamicObject is that I can override TryGetMember and TrySetMember methods, within which I need to raise events. But, how would a piece of code that adds a member whose name isn't known a priori look like?
sbenderli
@sbenderli - Then you can simply create new object that derives from your baseclass and this object can use Dictionary<string, object> to keep information about "unknown" properties.
Euphoric
Please see my update
sbenderli
@sbenderli: You can use TrySetMember etc for dynamic properties, but then also have an indexer which allows values to be set when the name is only known from a file etc. You can still raise events using the indexer.
Jon Skeet
@Jon: I will try out your suggestion. Thanks a lot!
sbenderli
+1  A: 

I'm not sure you want to use a dynamic object in this case.

dynamic in c# lets you do things like :

  dynamic something = GetUnknownObject();
  something.aPropertyThatShouldBeThere = true;

If you use an ExpandoObject, you can:

  var exp = GetMyExpandoObject();
  exp.APropertyThatDidntExist = "something";

Both of these let you use the propertyname as if it actually exists at compile time. In your case, you won't need to use this syntax at all, so I'm not sure that it would give you any benefit whatsoever. Instead, why not just use a Dictionary<string, object>, and:

var props = new Dictionary<string, object>();
   foreach( var someDefinintion in aFile)
   {
      props[ someDefinition.Name] = someDefinition.value;
   }

Because a Dictionary<string,object> is basically what an expando object is - but it has support for a different syntax. Yes, I'm simplifying - but if you're not using this from other code or through binding / etc, then this is basically true.

Philip Rieck
Please see my update
sbenderli
A: 

dynamic type is basicaly implemented as Property Bag. That means its dictionary of Keys (property names) and objects (here in non-type-safe way). Iam not use if you can access direcly into this dictionary, but you can use dictionary by yourself.

Damn, Jon Skeet was faster :(

Euphoric