سؤال

في ال protobuf-net. التنفيذ، ماذا البروتوخام سمة يعني، وماذا تفعل؟

مثال سيكون موضع تقدير.

رأيتها في هذا المنصب ولست متأكدا مما تفعله. المثال كان:

[Serializable,
 ProtoContract,
 ProtoInclude(50, typeof(BeginRequest))]
abstract internal class BaseMessage
{
  [ProtoMember(1)]
  abstract public UInt16 messageType { get; }
}

[Serializable,
 ProtoContract]
internal class BeginRequest : BaseMessage
{
    [ProtoMember(1)]
    public override UInt16 messageType
    {
        get { return 1; }
    }
}

أيضا، هل هناك طريقة لتوليد مثل هذه الميراث باستخدام protogen. أداة؟

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

المحلول

آسف، لم أقصد تفويت هذه الواحدة - للأسف، وأنا لا أرى كل شيء.

بالنظر إلى تفاصيل في السؤال، سأفترض أنك على الأقل على الأقل على الأقل .PROTO؛ صحح لي إن كنت مخطئ.

[ProtoInclude] يعمل كثيرا [XmlInclude] بالنسبة XmlSerializer - أو [KnownType] بالنسبة DataContractSerializer - يسمح لها بالتعرف على الفئات الفرعية من النوع أثناء (DE) التسلسل. الشيء الإضافي الوحيد هو أنه يحتاج إلى علامة (رقم) لتحديد كل نوع فرعي (يجب أن يكون فريدا، وليس الصدام مع أي من الحقول من النوع الأصل).

إعادة البروتين: كلا؛ المواصفات الأساسية (بواسطة Google) لا تقدم أي حكم للميراث على الاطلاق, ، لذلك ليس لدى البروتين (عبر .proto) أي آلية للتعبير عن هذا. Protobuf-Net يوفر دعم الميراث باعتباره تمديد, ، ولكن هل ذلك بطريقة لا تزال تترك الرسائل متوافقة مع التطبيقات الأخرى. في دفع، يمكن يمكنني إضافة دعم البروتسوجين عبر خصائص التمديد الجديد في مواصفات Google، لكنني لم أفعل ذلك بعد.

وبالتالي؛ أن ننظر إلى المثال؛ هذا يعبر عن علاقة الميراث بين BaseMessage و BeginRequest; ؛ بغض النظر عما إذا كنت تفعل:

Serialize<BaseMessage>(...)
Serialize<BeginRequest>(...)
  • في كلتا الحالتين، سيبدأ في القاعدة (BaseMessage) والعمل للأعلى؛ وهو ليس كذلك بالضبط صحيح - يكتب بيانات بدءا من BeginRequest (حتى يعرف أن لدينا BeginRequest في أقرب وقت ممكن أثناء التحضير). الشيء المهم هو أن يتم تضمين الحقول من أي أنواع العقود الأصل، وينظر المتسار إلى فعلي تم تمرير الكائن في - ليس فقط النوع الذي أنت قل أنه.

وبالمثل، أثناء التحلل، بغض النظر عما إذا كنت تستخدم:

Deserialize<BaseMessage>(...)
Deserialize<BeginRequest>(...)

سوف تحصل على النوع الذي تستسجل فعلا (يفترض BeginRequest).

تحت غطاء محرك السيارة، لأغراض التوافق (مع مواصفات المخازن المؤقتة البروتوكول الواسعة)، يشبه هذا لكتابة شيء مثل (اغفر أي أخطاء، بلدي .proto صدئ):

message BaseMessage {
    optional BeginRequest beginRequest = 50;
    optional uint32 messageType = 1;   
}
message BeginRequest {        
}

(تجاوز التجاوز لا ينبغي أن يحدد [ProtoMember], ، بالمناسبة.

عادة، ستكتب الحقول في ترتيب علامات تصاعدي، ولكن لجعل التحيز الفعال يختار المحرك أخيكنك كتابة بيانات الفئة الفرعية أول (الذي يسمح صراحة بالمواصفات) - أي يكتب شيئا مثل (عليك أن تتخيل الثنائية ...):

[tag 50, string][length of sub-message][body of sub-message][tag 1, int][value]

(في هذه الحالة، جسم الرسالة الفرعية فارغا)

هل هذا يغطي ذلك؟

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top