JSON.NET Newtonsoft с вложенным свойством класса, которому необходимо ссылаться на элемент в родительском классе [duplicate]

Вот еще одна вещь о одиночных играх, о которых никто еще не сказал.

В большинстве случаев «singletonity» является деталью реализации для некоторого класса, а не характеристикой его интерфейса. Inversion of Control Container может скрыть этот признак от пользователей класса; вам просто нужно отметить свой класс как одноэлементный (с аннотацией @Singleton в Java, например) и все; IoCC сделает все остальное. Вам не нужно предоставлять глобальный доступ к вашему экземпляру singleton, потому что доступ уже управляется IoCC. Таким образом, нет ничего плохого в IoC Singletons.

GoF Singletons в противоположность IoC Синглтоны должны выставлять «singletonity» в интерфейсе методом getInstance (), и поэтому они страдают от всего сказанного выше.

3
задан henningst 16 February 2016 в 10:12
поделиться

2 ответа

Вы можете полностью избавиться от родителя и использовать что-то вроде FindParent(node.Id), когда вам нужно его найти.

Если это не выполнимо (должно быть, хотя), и вам нужно иметь родительскую ссылку, мое предложение состояло бы в том, чтобы пройти через дерево и установить родительские ссылки после десериализации.

0
ответ дан tymtam 20 August 2018 в 19:44
поделиться
  • 1
    Да, это может сработать. Недостатком подхода FindParent (node.Id) является то, что мне всегда нужно использовать корневой отдел в качестве отправной точки. Иногда мне может потребоваться передать только детское отделение в качестве параметра для метода и иметь возможность легко перемещаться по дереву вверх. В настоящее время у меня есть рабочие версии обоих ваших предложений и они будут проверять их. Благодаря! – henningst 17 February 2016 в 16:50
  • 2
    – sɐunıɔןɐqɐp 26 September 2018 в 10:09

То, что я сделал, чтобы решить это, было игнорировать сериализацию родителя и реализовать публичное свойство «Дети», которое устанавливает мою личную коллекцию ChildrenDict. Когда я добавляю детей в частный словарь, я также устанавливаю свойство Parent для каждого дочернего элемента.

Лично я не люблю загрязнять классы данных спецификациями JSON, потому что мне нравится независимый чистый сериализатор.

Сказанное так, конечное решение не использует теги JsonIgnoreAttribute и определяет:

  • частный конструктор без параметров, используемый JSON deserializer
  • частное свойство родителя (игнорируется сериализатором JSON)
  • общедоступный метод GetParent () (для вашего собственного использования)
  • публичный конструктор, принимающий родительский аргумент (для вашего собственное использование)

Можно также определить метод SetParent (), хотя в моем коде мне это совсем не нужно.

Этот код был протестирован с NewtonsoftJson сериализация & amp; DotNET 4.5.2

using System.Collections.Generic;
using System.Linq;

namespace JsonSerializableNode
{
    public class Node
    {
        private Node() { } // used for deserializing

        public Node(string name, Node parent) // used everywhere else in your code
        {
            Name = name;
            Parent = parent;
        }

        public string Name { get; set; }

        private Node Parent { get; set; }

        public Node GetParent()
        {
            return Parent;
        }

        public Node[] Children
        {
            get
            {
                return ChildrenDict.Values.ToArray();
            }

            set
            {
                ChildrenDict.Clear();
                if (value == null || value.Count <= 0) return;
                foreach (Node child in value)
                    Add(child);
            }
        }

        // One could use a typed OrderedDictionary here, since Json lists guarantee the order of the children:
        private Dictionary<string, Node> ChildrenDict { get; } = new Dictionary<string, Node>();

        public Node Add(Node child)
        {
            ChildrenDict.Add(child.Name, child);
            child.Parent = this;
            return child;
        }

        public Node Get(string name)
        {
            return ChildrenDict[name];
        }

        public bool Remove(string name)
        {
            return ChildrenDict.Remove(name);
        }
    }
}
0
ответ дан sɐunıɔןɐqɐp 20 August 2018 в 19:44
поделиться
Другие вопросы по тегам:

Похожие вопросы: