protobuf и список<object> - как сериализовать / десериализовать?

StackOverflow https://stackoverflow.com/questions/923977

  •  06-09-2019
  •  | 
  •  

Вопрос

У меня есть List<object> с различными типами объектов в нем, такими как целые числа, строки и пользовательские типы.Все пользовательские типы настраиваются с помощью protobuf.Что я хочу сделать сейчас, так это сериализовать / десериализовать этот список с помощью protobuf.net.До сих пор я подозревал, что мне нужно явно объявлять каждый тип, что, к сожалению, невозможно с этими конструкциями со смешанным списком.Поскольку у программы форматирования двоичных файлов нет проблем с выполнением этих действий, я надеюсь, что я что-то пропустил и что вы сможете мне помочь.Итак, мой вопрос заключается в том, как обращаться с объектами в protobuf.net.

Это было полезно?

Решение

(раскрытие информации:Я автор protobuf-net)

BinaryFormatter является сериализатором на основе метаданных;т. е.он отправляет информацию о типе .NET для каждого сериализованного объекта.protobuf-net - это сериализатор на основе контрактов (двоичный эквивалент XmlSerializer / DataContractSerializer, который также отвергнет это).

В настоящее время не существует механизма транспортировки произвольный объекты, поскольку другой конец будет иметь ни за что от знания того, что вы отправляете;однако, если у вас есть известное множество из другой типы объектов, которые вы хотите отправить, могут быть разными.В конвейере также ведется работа по созданию расширяемых во время выполнения схем (а не просто атрибутов, которые фиксируются при сборке), но это далеко не завершено.


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

using System;
using System.Collections.Generic;
using ProtoBuf;
[ProtoContract]
[ProtoInclude(10, typeof(DataItem<int>))]
[ProtoInclude(11, typeof(DataItem<string>))]
[ProtoInclude(12, typeof(DataItem<DateTime>))]
[ProtoInclude(13, typeof(DataItem<Foo>))]
abstract class DataItem {
    public static DataItem<T> Create<T>(T value) {
        return new DataItem<T>(value);
    }
    public object Value {
        get { return ValueImpl; }
        set { ValueImpl = value; }
    }
    protected abstract object ValueImpl {get;set;}
    protected DataItem() { }
}
[ProtoContract]
sealed class DataItem<T> : DataItem {
    public DataItem() { }
    public DataItem(T value) { Value = value; }
    [ProtoMember(1)]
    public new T Value { get; set; }
    protected override object ValueImpl {
        get { return Value; }
        set { Value = (T)value; }
    }
}
[ProtoContract]
public class Foo {
    [ProtoMember(1)]
    public string Bar { get; set; }
    public override string ToString() {
        return "Foo with Bar=" + Bar;
    }
}
static class Program {
    static void Main() {
        var items = new List<DataItem>();
        items.Add(DataItem.Create(12345));
        items.Add(DataItem.Create(DateTime.Today));
        items.Add(DataItem.Create("abcde"));
        items.Add(DataItem.Create(new Foo { Bar = "Marc" }));
        items.Add(DataItem.Create(67890));

        // serialize and deserialize
        var clone = Serializer.DeepClone(items);
        foreach (DataItem item in clone) {
            Console.WriteLine(item.Value);
        }
    }
}

Другие советы

List<YourClass> list;
ProtoBuf.Serializer.Deserialize<List<YourClass>>(filestream);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top