Сериализовать класс MainClass с двумя приватными полями, которые являются элементами другого класса ChildClass - C#
Формулировка задачи:
Зравствуйте.
Цель: Сериализовать класс MainClass с двумя приватными полями, которые являются элементами другого класса ChildClass. В свою очередь, ChildClass содержит приватный List<int> и int. Хотелось бы использовать Xml-сериализацию с минимальным набором информации.
Проблемы:
1. Xml-сериализация приватных полей невозможна, так? Только бинарная... Не хотелось бы оставлять поля открытыми...
2. Какой вид Xml-сериализации мне лучше использовать для этих целей? Пробовал System.Xml.Serialization.XmlSerializer, System.Runtime.Serialization.Formatters.Soap.SoapFormatter. Soap не поддерживает стандартные коллекции. XmlSerializer довольно медленный (пока не критично), но Xml-код получается довольно грязным (нечитаемым), чего бы не хотелось.
Также пробовал XmlFormatter с codeproject.com, поскольку там обещали хорошую скорость и чистый (читаемый) XML. Но как применить его в моём случае - не разобрался. Как использовать автоматическую сериализацию - тоже.
3. Хотелось бы иметь возможность использовать как управляемую сериализацию (GetObjectData()), так и автоматическую с минимальными изменениями кода. Возможно ли это?
4. Имеется 2 поля, ссылающихся на ChildClass. Возможно ли сохранить один раз в Xml, если они ссылаются на один и тот же экземпляр в памяти? А если будет List<ChildClass>, возможно ли сохранить их лишь один раз?
По этому поводу нашёл следующую ссылку SerializationInfo - класс, но разобраться с тем, как это работает, и как это применить в моём случае, не смог...
Каких из проблем можно избежать и как?
Заранее спасибо.
Код:
//MainClass.cs
using System;
namespace MySerTrying
{
[Serializable]
public class MainClass// : ISerializable
{
public ChildClass cc1;
public ChildClass cc2;
public MainClass()
{
}
public void SetDefaults()
{
cc1 = new ChildClass(1);
cc2 = cc1; //or: new ChildClass(2);
}
public override string ToString()
{
return String.Format("{0}: {1}, {2}, cc1==cc2: {3}", this.GetType().Name, cc1, cc2, cc1 == cc2);
}
}
}//ChildClass.cs
using System;
using System.Collections.Generic;
namespace MySerTrying
{
[Serializable]
public class ChildClass
{
public List<int> lst;
public int val;
public ChildClass()
{
lst = new List<int>();
for (int i = 0; i < 1000; i++)
{
lst.Add(i);
}
}
public ChildClass(int val)
{
this.val = val;
}
public override string ToString()
{
return String.Format("{0}: {1}", this.GetType().Name, val);
}
}
}//Program.cs
using System;
//using DotNetMagazine.September.Examples;
using System.IO;
using System.Xml.Serialization;
//using System.Runtime.Serialization.Formatters.Soap;
//using System.Runtime.Serialization.Formatters.Binary;
namespace MySerTrying
{
class Program
{
static void Main(string[] args)
{
var cc = new MainClass();
cc.SetDefaults();
Console.WriteLine("Before Serialization. {0}\n", cc);
XmlSerializer XmlFmt = new XmlSerializer(typeof(MainClass));
using (var fs = new FileStream("MainClass.xml", FileMode.Create))
{
XmlFmt.Serialize(fs, cc);
}
cc = null;
using (var fs = new FileStream("MainClass.xml", FileMode.Open))
{
cc = (MainClass)XmlFmt.Deserialize(fs);
}
Console.WriteLine("After Deserialization. {0}\n", cc);
Console.ReadLine();
}
}
}Решение задачи: «Сериализовать класс MainClass с двумя приватными полями, которые являются элементами другого класса ChildClass»
textual
Листинг программы
using MyListsLib;
using SerMyList.Classes;
using System;
using System.Xml.Serialization;
using System.IO;
namespace SerMyList
{
class Program
{
static void Main(string[] args)
{
var mel = new MyEventList<CheckClass>();
mel.Name = "test";
mel.OnAddElem += new MyEventsLib.EventArgs.OnAddEventHandler(mel_OnAddElem);
for (int i = 0; i < 100; ++i)
{
mel.Add(new CheckClass() { IntProp = i, StrProp = "test" + i });
}
XmlSerializer XmlFmt = new XmlSerializer(typeof(MyEventList<CheckClass>));
using (var fs = new FileStream("MEL.xml", FileMode.Create))
{
XmlFmt.Serialize(fs, mel);
}
mel = null;
using (var fs = new FileStream("MEL.xml", FileMode.Open))
{
mel = (MyEventList<CheckClass>)XmlFmt.Deserialize(fs);
}
if (mel != null)
{
Console.WriteLine(mel.Name);
foreach (var element in mel)
{
Console.WriteLine("{0} - {1}", element.IntProp, element.StrProp);
}
}
Console.ReadLine();
}
static void mel_OnAddElem(object sender, MyEventsLib.EventArgs.MessageEventArgs.OneEventerEventArgs.OnAddEventArgs e)
{
Console.WriteLine(e.Message);
}
}
}