문제

나는있다 List<object> 정수, 문자열 및 사용자 정의 유형과 같은 다른 유형의 객체가 있습니다. 모든 사용자 지정 유형은 프로토 비프 조정입니다. 지금하고 싶은 것은 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