Страницы

Поиск по вопросам

среда, 29 января 2020 г.

Сериализация и Десериализация C#

#c_sharp #net


Имеется некий класс, который необходимо сериализовать, т.е. получить массив байт
в переменную. Какими способами это можно сделать?, Пробовал написать с помощью интерфейса
ISerializable. Есть ли другие хорошие способы?
Например класс:
class cTestMessageClass
{
    public int A { get; set; }
    public double B { get; set; }
    public string C { get; set; }
    private Int64 D { get; set; }
}
    


Ответы

Ответ 1



Воспользуйтесь встроенной сериализацией. Для этого достаточно дать классу атрибут Serializable: [Serializable] class TestMessage { public int A { get; set; } public double B { get; set; } public string C { get; set; } private Int64 D { get; set; } } Если вам и правда нужна бинарная сериализация (означающая потенциальные проблемы при работе в гетерогенной системе), используйте BinaryFormatter: class Program { static void Main(string[] args) { TestMessage tm1 = ...; var stream = Save(tm1); stream.Seek(0, SeekOrigin.Begin); var tm2 = Load(stream); } static Stream Save(TestMessage tm) { var formatter = new BinaryFormatter(); var stream = new MemoryStream(); formatter.Serialize(stream, tm); return stream; } static TestMessage Load(Stream s) { var formatter = new BinaryFormatter(); var tm = (TestMessage)formatter.Deserialize(s); return tm; } } В качестве альтернативы можно использовать XML-сериализацию, но учтите, что она "из коробки" игнорирует приватные свойства, так что нужно будет либо имплементировать ISerializable/IXmlSerializable, либо использовать DataContractSerializer вместо XmlSerializer.

Ответ 2



Я использовал JSON.NET для сериализации и остался им очень доволен! ваш пример будет выглядеть в нем вот так: using Newtonsoft.Json; using Newtonsoft.Json.Converters; [JsonObject(MemberSerialization.OptIn)] [JsonConverter(typeof(cTestMessageClassConverter ))] class cTestMessageClass { [JsonProperty] public int A { get; set; } [JsonProperty] public double B { get; set; } [JsonProperty] public string C { get; set; } [JsonProperty] private Int64 D { get; set; } } // Конвертер JSON public class cTestMessageClassConverter : CustomCreationConverter { public override cTestMessageClass Create(Type objectType) { return new cTestMessageClass(); } } Сериализация: string s = JsonConvert.SerializeObject(testMessage); //десериализация cTestMessageClass cd = JsonConvert.DeserializeObject(z);

Ответ 3



Сериализуйте в xml.

Ответ 4



Если нужна быстрая сериализация, то придется отказаться от штатной реализации. В вашем случае это может выглядеть так: interface ISupportsBinarySerialization { void Serialize(out byte[] buffer); void Serialize(BinaryWriter writer); void Deserialize(byte[] buffer); void Deserialize(BinaryReader reader); } class TestMessageClass : ISupportsBinarySerialization { public int A { get; set; } public double B { get; set; } public string C { get; set; } private long D { get; set; } public void Serialize(out byte[] buffer) { var size = 0 + sizeof(int) + sizeof(double) + sizeof(int) + sizeof(char)*C.Length + sizeof(long); buffer = new byte[size]; var stream = new MemoryStream(buffer); var writer = new BinaryWriter(stream, Encoding.Unicode); Serialize(writer); writer.Dispose(); stream.Dispose(); } public void Serialize(BinaryWriter writer) { writer.Write(A); writer.Write(B); var str = Encoding.Unicode.GetBytes(C); writer.Write(str.Length); writer.Write(str); writer.Write(D); } public void Deserialize(byte[] buffer) { var stream = new MemoryStream(buffer); var reader = new BinaryReader(stream, Encoding.Unicode); Deserialize(reader); reader.Dispose(); stream.Dispose(); } public void Deserialize(BinaryReader reader) { A = reader.ReadInt32(); B = reader.ReadDouble(); var strLen = reader.ReadInt32(); C = Encoding.Unicode.GetString(reader.ReadBytes(strLen)); D = reader.ReadInt64(); } }

Ответ 5



Когда я пробовал сериализацию в .net, возникали накладки с различной версией сборок и еще чем то, т.е. это был не просто гибкий набор байт. Как хороший вариант могу предложить делать сериализацию вручную, в байтах или xml: long V = 42; //байты: byte[] = BitConverter.GetBytes(V); //xml: xdoc.AddNode(string.Format("{1}",V,V.GetType())); Конечно, необходима еще и структура. Ну и соответственно смотря для каких целей приложение.

Комментариев нет:

Отправить комментарий