سؤال

انا املك List<object> مع أنواع مختلفة من الكائنات في مثل الأعداد الصحيحة والسلاسل وأنواع مخصصة. جميع الأنواع المخصصة التي يتم ضبطها protobuf. ما أريد القيام به الآن هو تسلسل / تحيز هذه القائمة مع protobuf.net. حتى الآن أظن أنني يجب أن أعلن كل نوع وكل نوع صريح، وهذا أمر غير ممكن للأسف مع هذه الإنشاءات المختلطة. نظرا لأن النظرة الثنائية لا تحتوي على مشاكل للقيام بهذه الأشياء التي آمل أن أفتقد شيئا ويمكنك مساعدتي بها. لذلك سؤالي هو كيفية التعامل مع الكائنات في protobuf.net.

هل كانت مفيدة؟

المحلول

(الإفصاح: أنا مؤلف Protobuf-Net)

BinaryFormatter هو تسلسل في البيانات الوصفية؛ أي أنه يرسل .NET نوع المعلومات حول كل كائن Serialized. 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