Динамическое создание объекта с динамическими дочерними элементами с использованием данных во время выполнения с помощью ExpandoObject в C#

Я создал динамический объект и установил для него свойства и значения во время выполнения с помощью ExpandoObject.

    dynamic parentDynamic = new ExpandoObject();

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

    Console.WriteLine(parentDynamic.GroupOne);

Консоль успешно выводит «по умолчанию», как и ожидалось.

Я также создал дочерний объект с несколькими свойствами таким же образом.

    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);

Консоль успешно выводит «Сантехник», как и ожидалось.

Где я попадаю в пробку, так это когда я пытаюсь добавить объект childDynamic к объекту parentDynamic и дать ему имя во время выполнения. Вот моя последняя неудачная попытка:

    var childName = "ChildOne";

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

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

Ошибка, которую я получаю при попытке присвоения: Невозможно привести объект типа «System.String» к типу «System.Collections.Generic.IDictionary`2[System.String,System.Object]».

По сути, я хотел бы иметь доступ к parentDynamic.GroupOne.ChildOne.Occupation и вернуть «Сантехник» или parentDynamic.GroupOne.ChildOne.FirstName и вернуть «Джон»

Изначально я пытался сделать все задания сразу, вот так

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

Но я получаю сообщение об ошибке Невозможно применить индексирование с помощью [] к выражению типа «System.Dynamic.ExpandoObject». Вот почему я пошел по пути создания родительского и дочернего объектов и приведения их к словарю. объекты в первую очередь. В идеале я хотел бы просто сделать что-то подобное выше, поскольку это НАМНОГО проще.


person INNVTV    schedule 17.06.2016    source источник
comment
Ну, вы устанавливаете тип для строки, чуть выше. Его значение будет default, а затем вы пытаетесь привести это значение к словарю.   -  person Rob    schedule 17.06.2016
comment
Но я также не могу использовать его как словарь в словаре, не так ли? Я попробовал несколько вариантов этого безрезультатно. ((IDictionary‹IDictionary‹String, Object›, Object›)parentDynamic)[parentName] = по умолчанию;   -  person INNVTV    schedule 17.06.2016
comment
Не уверен, что именно вы имеете в виду, но использование dynamic не позволяет вам приводить типы к недопустимым типам. В приведенном выше комментарии parentDynamic.GroupOne = "default"; и далее вы пытаетесь сделать вид, что parentDynamic.GroupOne — это словарь, а это не так. Вместо того, чтобы назначать ему "default", вы должны назначить ему словарь   -  person Rob    schedule 17.06.2016
comment
Взгляните на эта статья.   -  person Jeroen Heier    schedule 17.06.2016
comment
Имеет ли смысл делать назначения все сразу, вот так parentDynamic["GroupOne"]["ChildOne"].Occupation = "Plumber", но я получаю сообщение об ошибке Невозможно применить индексирование с помощью [] к выражению типа 'System.Dynamic.ExpandoObject'   -  person INNVTV    schedule 17.06.2016
comment
Извините за опечатку выше, вот мой идеальный способ обработки этого назначения: parentDynamic["GroupOne"]["ChildOne"].["Occupation"] = "Plumber" но я получаю сообщение об ошибке Невозможно применить индексирование с помощью [] к выражению типа 'System.Dynamic.ExpandoObject' Обработка этого в одной строке предпочтительнее создавать родительские/дочерние объекты. Я отредактировал свой вопрос выше, чтобы добавить это.   -  person INNVTV    schedule 17.06.2016


Ответы (1)


Чтобы иметь возможность использовать синтаксис parentDynamic.GroupOne.ChildOne, свойство GroupOne также должно быть динамическим ExpandoObject, тогда как в вашем случае это string.

Что-то вроде этого:

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";

или с IDictionary<string, object> приведениями:

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);
person Ivan Stoev    schedule 17.06.2016
comment
Спасибо, Иван, но так как это должно быть сделано во время выполнения, я должен сделать что-то вроде этого: dynamic parentDynamic = new ExpandoObject(); parentDynamic["GroupOne"] = new ExpandoObject(); parentDynamic["GroupOne"]["ChildOne"] = new ExpandoObject(); parentDynamic["GroupOne"]["ChildOne"]["Occupation"] = "Plumber"; Все строки являются динамическими переменными во время выполнения. С приведенным выше я получаю эту ошибку: Невозможно применить индексирование с помощью [] к выражению типа «System.Dynamic.ExpandoObject» - person INNVTV; 17.06.2016
comment
Ну, это просто пример. Важная часть — сделать GroupOne свойством ExpandoObject. Затем во время выполнения вы можете привести его к IDictionary<string, object>, как в вашем коде. - person Ivan Stoev; 17.06.2016
comment
Спасибо, Иван. Это было именно то руководство, которое мне было нужно! - person INNVTV; 17.06.2016