1

I've created a dynamic object and set properties and values to it at runtime using ExpandoObject

    dynamic parentDynamic = new ExpandoObject();

    var parentName = "GroupOne";
    ((IDictionary<String, Object>)parentDynamic)[parentName] = "default";

    Console.WriteLine(parentDynamic.GroupOne);

The Console successfully outputs "default" as expected.

I've also created a child object with multiple properties in the same manner

    dynamic childDynamic = new ExpandoObject();

    var childProperty1 = "FirstName";
    var childProperty2 = "LastName";
    var childProperty3 = "Occupation";

    ((IDictionary<String, Object>)childDynamic)[childProperty1] = "John";
    ((IDictionary<String, Object>)childDynamic)[childProperty2] = "Smith";
    ((IDictionary<String, Object>)childDynamic)[childProperty3] = "Plumber";

    Console.WriteLine(childDynamic.Occupation);

The Console successfully outputs "Plumber" as expected.

Where I am getting in a jam is when I attempt to add the childDynamic object to the parentDynamic object and give it a name at runtime. Here is my latest failed attempt:

    var childName = "ChildOne";

    ((IDictionary<String, Object>)((IDictionary<String, Object>)parentDynamic)[parentName])[childName] = childDynamic;

    Console.Write(parentDynamic.GroupOne.ChildOne.Occupation);

The error I am getting when attempting the assignment is: Unable to cast object of type 'System.String' to type 'System.Collections.Generic.IDictionary`2[System.String,System.Object]'.

Essentially I would like to be able access parentDynamic.GroupOne.ChildOne.Occupation and get back "Plumber" or parentDynamic.GroupOne.ChildOne.FirstName and get back "John"

Originally I was trying to make my assignments all at once like so

 parentDynamic["GroupOne"]["ChildOne"]["Occupation"] = "Plumber"

But I get the error Cannot apply indexing with [] to an expression of type 'System.Dynamic.ExpandoObject' Which is why I went down the path of creating a parent and child object and casting them as Dictionary objects first. Ideally I would like to just do something like the above as it's MUCH simpler.

INNVTV
  • 3,155
  • 7
  • 37
  • 71
  • 1
    Well, you're setting the type to a string, just above. It's value will be `default`, and then you're trying to cast that value to a dictionary. – Rob Jun 17 '16 at 06:02
  • But I also can't cast it as a Dictionary within a Dictionary can I? I tried a few variations of this to no avail. ((IDictionary, Object>)parentDynamic)[parentName] = "default"; – INNVTV Jun 17 '16 at 06:10
  • Not sure what you mean exactly, but using dynamic doesn't allow you to cast types to invalid types. In your above comment, `parentDynamic.GroupOne = "default";`, and later you're trying to pretend that `parentDynamic.GroupOne` is a dictionary, which it's not. Instead of assigning it `"default"`, you should assign it a dictionary – Rob Jun 17 '16 at 06:12
  • Have a look at [this](https://blogs.msdn.microsoft.com/csharpfaq/2009/09/30/dynamic-in-c-4-0-introducing-the-expandoobject) article. – Jeroen Heier Jun 17 '16 at 06:15
  • Does it make more sense to make the assignments all at once like so `parentDynamic["GroupOne"]["ChildOne"].Occupation = "Plumber"` but I get an error **Cannot apply indexing with [] to an expression of type 'System.Dynamic.ExpandoObject'** – INNVTV Jun 17 '16 at 06:19
  • Sorry typo above, here is my ideal way to handle this assignment: `parentDynamic["GroupOne"]["ChildOne"].["Occupation"] = "Plumber"` but I get the error **Cannot apply indexing with [] to an expression of type 'System.Dynamic.ExpandoObject'** Handling this in one line would be preferred to making parent/child objects. I edited my question above to add this. – INNVTV Jun 17 '16 at 06:26

1 Answers1

1

In order to be able to use parentDynamic.GroupOne.ChildOne syntax, GroupOne property should also be dynamic ExpandoObject while in your case it is a string.

Something like this:

dynamic parentDynamic = new ExpandoObject();
parentDynamic.GroupOne = new ExpandoObject();
parentDynamic.GroupOne.ChildOne = new ExpandoObject();
parentDynamic.GroupOne.ChildOne.FirstName = "John";
parentDynamic.GroupOne.ChildOne.LastName = "Smith";
parentDynamic.GroupOne.ChildOne.Occupation = "Plumber";

or with IDictionary<string, object> casts:

IDictionary<string, object> parent = new ExpandoObject();
IDictionary<string, object> group = new ExpandoObject();
IDictionary<string, object> child = new ExpandoObject();
child["FirstName"] = "John";
child["LastName"] = "Smith";
child["Occupation"] = "Plumber";
parent["GroupOne"] = group;
group["ChildOne"] = child;
dynamic parentDynamic = parent;
Console.WriteLine(parentDynamic.GroupOne.ChildOne.Occupation);
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • Thanks Ivan, but since this has to be done at runtime I have to do something like this: `dynamic parentDynamic = new ExpandoObject(); parentDynamic["GroupOne"] = new ExpandoObject(); parentDynamic["GroupOne"]["ChildOne"] = new ExpandoObject(); parentDynamic["GroupOne"]["ChildOne"]["Occupation"] = "Plumber";` The strings are all dynamic variables at runtime. With the above I get this error: **Cannot apply indexing with [] to an expression of type 'System.Dynamic.ExpandoObject'** – INNVTV Jun 17 '16 at 06:37
  • Well, it's just an example. The important part is to make `GroupOne` property `ExpandoObject`. Then at runtime you can cast it to `IDictionary` as in your code. – Ivan Stoev Jun 17 '16 at 07:14
  • Thank you Ivan. That was exactly the guidance I needed! – INNVTV Jun 17 '16 at 16:57