Как десериализовать словарь с иерархическими ключами для динамического объекта? - PullRequest
3 голосов
/ 09 февраля 2012

Я получаю данные в виде словаря и хочу десериализовать их в динамический объект. Искривление словаря ключей выражает иерархический объект. Второй поворот заключается в том, что некоторые ключи выражают свойство массива и / или словаря.

Например:

===========Key================ ======Value========
Person.First                  | John
Person.Last                   | Doe
Person.Phone[Work]            | 999-555-1234
Person.Phone[Home]            | 999-555-1235
Person.Addresses[Home].Street | 101 My Street
Person.Addresses[Home].City   | AnyTown
Person.Spouse.First           | Jane
Person.Spouse.Last            | Doe
Person.Insurance[0].Name      | Medicare
Person.Insurance[0].GroupNum  | 1234567

Редактировать : Добавлены примеры массивов

Я пытаюсь найти простой метод создания объекта, который затем можно использовать в оценщике выражений времени выполнения.

Вот моя первая попытка, которая работает для простых свойств, но не пытается обработать массивы

public static class DynamicBuilder
{
    public static object Build(IDictionary<string, object> dict)
    {

        ExpandoObject root = new ExpandoObject();

        foreach (var item in dict)
        {
            var objDict = (IDictionary<string, object>)root;

            var parts = item.Key.Split('.');

            for (int i = 0; i < parts.Length ; i++)
            {
                string propName = parts[i];

                if (i < parts.Length - 1)
                {
                    if (!objDict.ContainsKey(propName))
                    {
                        dynamic temp = new ExpandoObject();
                        objDict.Add(propName, temp);
                        objDict = (IDictionary<string, object>)temp;
                    }
                    else
                    {
                        objDict = (IDictionary<string, object>)objDict[propName];
                    }

                }
                else
                {
                    if (objDict.ContainsKey(propName))
                        objDict[propName] = item.Value;
                    else
                        objDict.Add(propName, item.Value);

                }

            }

        }

        return root;
    }

}

Есть идеи, как лучше подойти к этому?

Спасибо

1 Ответ

0 голосов
/ 17 мая 2012

Простой способ - создать пользовательский объект, такой как

public class DictObject
{
   public String value;
   public Dictionary<string, DictObject> children;
}

. Ваш основной словарь будет просто Dictionary<string, DictObject> объектом.Для каждого имени свойства вы добавляете словарную запись и значение или дочерний словарь для дочерних элементов.

Таким образом, вы бы загрузили Person.First так, чтобы к нему обращались как

 MainDict("Person").children("First").Value 

И, используя этот подход, вы могли бы просто представить свои словарные и массивные записи так же, как . детей, а не относиться к ним особенным.Визуализируйте свои данные следующим образом:

===========Key================ ======Value========
Person.First                  | John
Person.Last                   | Doe
Person.Phone.Work             | 999-555-1234
Person.Phone.Home             | 999-555-1235
Person.Addresses.Home.Street  | 101 My Street
Person.Addresses.Home.City    | AnyTown
Person.Spouse.First           | Jane
Person.Spouse.Last            | Doe
Person.Insurance.0.Name       | Medicare
Person.Insurance.0.GroupNum   | 1234567

Таким образом, к значениям можно будет обращаться следующим образом:

 MainDict("Person").children("Insurance").children("0").children("Name").Value 

И вы всегда можете добавить свойства в DictObject, если хотите отслеживать словарь /массив, если вы хотите снова вывести тот же текстовый файл.

...