.net сериализация

193
22 февраля 2018, 11:24

Всем привет. На учебе дали такое задание. Но я совсем не понимаю логику и не понимаю как начать. Остановился на том, что создал 4 класса, как указано. 1 Абстрактный и 3 наследника.

Что дальше делать нет мыслей. Подскажите, пожалуйста, буду очень благодарен за наводку.

public abstract class BaseHolder
{
}
public class IntHolder : BaseHolder
{ 
}
public class CharArrayHolder : BaseHolder
{ 
}
public class DoubleHolder : BaseHolder 
{ 
}

И не пойму совершенно по какому принципу разделяется в дереве, как в примере.

А главное, что должно получиться в итоге? текстовый или xml файл с данными? или аналогичное дерево?

Пожалуйста, не пинайте, рад любой помощи.

UPD. Какие варианты могут быть визуализации задания?

Answer 1

Отделим данные от древовидной структуры:

public abstract class BaseHolder
{
    public abstract object BaseValue { get; }
    public override string ToString()
    {
        return BaseValue.ToString();
    }
}
public class IntHolder : BaseHolder
{
    public int Value { get; set; }
    public override object BaseValue { get { return Value; } }
}
public class CharArrayHolder : BaseHolder
{
    public char[] Value { get; set; }
    public override object BaseValue { get { return Value; } }
    public override string ToString()
    {
        return string.Join("", Value);
    }
}
public class DoubleHolder : BaseHolder
{
    public double Value { get; set; }
    public override object BaseValue { get { return Value; } }
}
public class HolderNode<T>
{
    public T Data { get; private set; }
    public List<HolderNode<T>> Children { get; private set; }
    public HolderNode(T aData)
    {
        Data = aData;
        Children = new List<HolderNode<T>>();
    }
}

Тест:

class Program
{
    private static void WriteNode(HolderNode<BaseHolder> aNode, int aLevel)
    {
        for(int i = 0; i < aLevel; i++)
            Console.Write("    ");
        Console.WriteLine(aNode.Data.ToString());
        for (int i = 0; i < aNode.Children.Count; i++)
            WriteNode(aNode.Children[i], aLevel + 1);
    }
    static void Main(string[] args)
    {
        // создание дерева как на картинке
        HolderNode<BaseHolder> root = new HolderNode<BaseHolder>(new IntHolder() { Value = 1 });
        HolderNode<BaseHolder> _2011 = new HolderNode<BaseHolder>(new IntHolder() { Value = 2011 });
        HolderNode<BaseHolder> fulcrum = new HolderNode<BaseHolder>(new CharArrayHolder() { Value = "FULCRUM".ToCharArray() });
        fulcrum.Children.Add(new HolderNode<BaseHolder>(new CharArrayHolder() { Value = "LINUX".ToCharArray() }));
        fulcrum.Children.Add(new HolderNode<BaseHolder>(new IntHolder() { Value = 7 }));
        _2011.Children.Add(fulcrum);
        root.Children.Add(_2011);
        root.Children.Add(new HolderNode<BaseHolder>(new CharArrayHolder() { Value = "C++".ToCharArray() }));
        HolderNode<BaseHolder> pi = new HolderNode<BaseHolder>(new DoubleHolder() { Value = 3.14 });
        pi.Children.Add(new HolderNode<BaseHolder>(new CharArrayHolder() { Value = "TEST".ToCharArray() }));
        pi.Children.Add(new HolderNode<BaseHolder>(new IntHolder() { Value = 9 }));
        pi.Children.Add(new HolderNode<BaseHolder>(new IntHolder() { Value = 6 }));
        root.Children.Add(pi);
        // рекурсивный вывод в консоль
        WriteNode(root, 0);
        Console.ReadLine();
    }
}

Консольный вывод:

1
    2011
        FULCRUM
            LINUX
            7
    C++
    3.14
        TEST
        9
        6
Answer 2

В каждом из ваших классов напишите по два поля, условно:

object data;
BaseHolder parent;

Соответственно, у корня дерева parent будет равен null, а у других элементов ссылаться на родителя.

После этого любой сериализатор в любом формате сохранит все нужные данные (а десериализатор, соответственно, восстановит).

Примеров той же самой XML-сериализации чуть больше, чем очень много.

Answer 3

Для сериализации лучше не использовать object, тем более что есть базовый класс, так будет выглядеть система классов:

[DataContract]
public abstract class BaseHolder
{
    [DataMember]
    public BaseHolder[] Children {get; set;}
}
[DataContract]
public class IntHolder : BaseHolder
{
    [DataMember]
    public int Val {get; set;}
}
[DataContract]
public class CharArrayHolder : BaseHolder
{
    [DataMember]
    public char[] Val {get; set;}
}
[DataContract]
public class DoubleHolder : BaseHolder 
{ 
    [DataMember]
    public double Val {get; set;}
}

Для хранения лучше всего использовать xml, так же можно добавить генерализацию. Для корректной сериализации лучше всего использовать DataContractSerializer. После декларации типов для сериализации можно использовать штатный XmlSerializer...

READ ALSO
Отправка сообщения клиенту от сервера c#

Отправка сообщения клиенту от сервера c#

Доброго времени сутокПытаюсь наладить передачу сообщения от клиента другому клиенту через сервер(использую TcpListener/TcpClient)

248
Не работает нажатие на InlineKeyboardButton

Не работает нажатие на InlineKeyboardButton

Работа с TelegramBot Описываю бота

276
C# Ошибка SQL Error 52 на другом компе

C# Ошибка SQL Error 52 на другом компе

Имеется программа на C# с базой данных (MS SQL), использую Visual Studio 2015Что делать? app

228
Показать скрытую форму через открытую

Показать скрытую форму через открытую

Здравствуйте! На главном окне у меня присутствует авторизация, при успешном её прохождении появляется новое окно, а главное скрывается:

167