Marc在stackoverflow上提到,protobuf-net的v2中有可能使用ProtoInclude屬性(或類似方法)來序列化/反序列化類層次結構,而無需指定基類中的每個子類型。這是否實現了?我們有一個可以在外部庫中派生的插件接口,因此無法知道派生類型是什麼。儘管我們可以在類型之間保持唯一的編號,但我無法在網絡上找到任何示例,因爲使用ProtoInclude屬性時需要指定子類型。protobuf-net繼承
如果我不知道子類是什麼,我該如何去實現與protobuf-net的繼承?
Marc在stackoverflow上提到,protobuf-net的v2中有可能使用ProtoInclude屬性(或類似方法)來序列化/反序列化類層次結構,而無需指定基類中的每個子類型。這是否實現了?我們有一個可以在外部庫中派生的插件接口,因此無法知道派生類型是什麼。儘管我們可以在類型之間保持唯一的編號,但我無法在網絡上找到任何示例,因爲使用ProtoInclude屬性時需要指定子類型。protobuf-net繼承
如果我不知道子類是什麼,我該如何去實現與protobuf-net的繼承?
如果你不能在屬性指定亞型(因爲它不是在編譯時知道),你有2個選項(兩者僅適用於「V2」,可作爲測試版):
RuntimeTypeModel
而不是靜態的Serializer
方法(它們現在只是RuntimeTypeModel.Default
的快捷方式);講述繼承(如下所示)模型第二添加DynamicType = true
到[ProtoMember(...)]
是不是很純的protobuf - 它嵌入類型信息,我真的不愛但人們只要保持要求。第一個是我的首選。在運行時添加亞型:
var model = TypeModel.Create();
var type = model.Add(typeof(YourBaseType), true);
var subTypeA = model.Add(typeof(SomeSubType), true);
var subTypeB = model.Add(typeof(SomeOtherSubType), true);
type.AddSubType(4, typeof(SomeSubType));
type.AddSubType(5, typeof(SomeOtherSubType));
在上述裝置中的true
「使用正常規則來自動添加成員屬性」 - 也可以利用這一控制和指定的屬性(等),如果手動你喜歡。
請注意,TypeModel
應該被緩存和重用(不是爲每個需要序列化的對象創建),因爲它包含一些「發出」代碼以生成方法。重新使用它會更快,並且需要更少的內存。類型模型是線程安全的,可用於在不同線程上併發地序列化/反序列化多個流。
爲了進一步擴大馬克的回答,專門處理RuntimeTypeModel
,這是寫的一種方式:
RuntimeTypeModel.Default[typeof(BaseClass)].AddSubType(20, typeof(DerivedClass));
如果從派生類派生多個類,將它們鏈接這樣
RuntimeTypeModel.Default[typeof(DerivedClass)].AddSubType(20, typeof(DerivedFromDerivedClass));
等。
然後,您可以像使用protobuf-net一樣使用Serializer.Serialize(file,object)
。
這適用於不同的項目和命名空間。
非常感謝BRILLIANT。這適用於我的場景。 – Asheh 2016-05-11 14:16:02
通過添加輔助擴展方法:
public static class RuntimeTypeModelExt
{
public static MetaType Add<T>(this RuntimeTypeModel model)
{
var publicFields = typeof(T).GetFields().Select(x => x.Name).ToArray();
return model.Add(typeof(T), false).Add(publicFields);
}
}
,您可以簡化分登記註冊類型是這樣的:
private static RuntimeTypeModel CreateModel()
{
var model = TypeModel.Create();
model.Add<ExportInfo>();
model.Add<RegistrationInfo>();
model.Add<FactorySetupInfo>()
.AddSubType(101, model.Add<ServiceSetupInfo>().Type)
.AddSubType(102, model.Add<GenericWrapperSetupInfo>().Type)
.AddSubType(103, model.Add<DecoratorSetupInfo>().Type);
return model;
}
很好,謝謝。這就是我期待的,但不知道它是如何工作的。自動屬性映射是一個很好的接觸。我們打算通過預編譯postharp屬性來做到這一點,但這樣做會更好。 – 2011-06-06 06:37:14
@重要的是澄清,在這種情況下,「自動」意味着「從像XmlElement,DataMember或ProtoMember」。 *還*內置支持按字母順序排列的隱式字段,但它更脆弱 - 您需要注意這一點。 – 2011-06-06 06:40:55
@Marc ** 1)**我可以使用屬性定義一些具有相同基本類型的子類型,然後在運行時添加更多的子類型嗎? ** 2)**爲什麼代碼中的第3行和第4行是必需的? Arent他們多餘,如果你添加第5和第6行? – Rotem 2014-01-22 14:29:37