protobuf-net v2 是否需要 DataMember(Order=n) 注释? [英] Is DataMember(Order=n) annotation required for protobuf-net v2?
问题描述
简单实验:我从 Northwind 创建了一个实体模型,发现生成的类在不添加 Order
属性的情况下不适用于 protobuf-net v2.有没有办法让实体代码生成器添加Order
,或者有没有办法让protobuf-net在没有Order
的情况下工作?
Simple experiment: I created an entity model from Northwind, and find that the generated classes don't work for protobuf-net v2 without adding the Order
property. Is there a way to get the entity code generator to add Order
, or is there a way to get protobuf-net to work without Order
?
我必须改变
[DataMemberAttribute()]
到
[DataMemberAttribute(Order=1)]
等
NorthwindEntities e = new NorthwindEntities();
using(var file = File.Create("customers.bin"))
{
Serializer.Serialize(file, e.Customers);
}
推荐答案
要求是它有一种方法可以将成员解析为数字键.这个可以采用内联属性的形式——例如,它允许 [DataContract]
/[DataMember(Order=key)]
, [XmlType]
/[XmlElement(Order=key)]
或 [ProtoContract]
/[ProtoMember(key)]
.
What is required is that it has a way to resolve members to numeric keys. This can take the form of inline attributes - for example, it allows [DataContract]
/[DataMember(Order=key)]
, [XmlType]
/[XmlElement(Order=key)]
, or [ProtoContract]
/[ProtoMember(key)]
.
还可以通过 [DataContract]
选择按字母顺序推断合同,但这只有在您的合同类型不会改变时才安全强>在未来;为此,请添加:
There are also options via [DataContract]
to infer the contract alphabetically, but this is only safe if your contract type is not going to change in the future; to do this, add:
[ProtoContract(InferTagFromName = true)]
到类型(也许是部分的,见下文).这直接适用于您呈现的场景,其中[DataMember]
表示成员,但没有定义Order
.为了稳定性,我个人更喜欢显式布局.
to the type (perhaps in a partial, see below). This applies directly to the scenario you present, where [DataMember]
indicates the members, but there is no defined Order
. Personally I prefer explicit layouts, for stability.
另一个选项甚至不需要像 [DataMember]
这样的提示;您可以要求它应用 BinaryFormatter
规则(所有字段,公共或私有)或 XmlSerializer
规则(公共成员、属性或字段);不过,如果您的类型发生变化,这会非常不稳定!
Another option doesn't even need hints like [DataMember]
; you can ask it to apply either BinaryFormatter
rules (all fields, public or private), or XmlSerializer
rules (public members, properties or fields); again, though, this is very unstable if your type changes!
[ProtoContract(ImplicitFields = ImplicitFields.AllPublic)]
但是;另一个常见的情况是您的类型来自生成器,您无法方便地对其进行编辑,因为任何编辑都会在重新生成时丢失;对于那个场景,partial
类可能会有所帮助.您不能通过属性向成员添加属性,但是 [ProtoPartialMember]
可以在这里提供帮助.例如,在单独的代码文件中:
But; another common scenario is that you have types coming from a generator, that you can't conveniently edit, since any edits would get lost at re-generation; for that scenario, partial
classes can be helpful. You can't add attributes to members via attributes, but [ProtoPartialMember]
can help here. For example, in a separate code file:
[ProtoContract]
[ProtoPartialMember(key, memberName)]
[ProtoPartialMember(anotherKey, anotherMemberName)]
...
public partial class Order {}
有时,您无权访问任何类型,因此添加任何类型的属性都不是一种选择.如果您的场景如您所描述的([DataContract/
[DataMember], no
Order`),则 lazy 选项是全局启用此功能:
Sometimes, you have no access whatsoever to the type, so adding attributes of any kind is not an option. If your scenario is as you describe ([DataContract/
[DataMember], no
Order`), then a lazy option is to enable this globally:
Serializer.GlobalOptions.InferTagFromName = true;
或在 v2 中:
RuntimeTypeModel.Default.InferTagFromNameDefault = true;
对于更复杂的场景,v2 有一个新的 MetaType
模型专门用于此,您可以在运行时配置布局:
For more complex scenarios, v2 has a new MetaType
model devoted to this, where you can configure the layout at runtime:
RuntimeTypeModel.Default.Add(typeof(Order), false)
.Add(key, memberName).Add(anotherKey, anotherMemberName);
或者如果你的键是 1, 2, 3, ... 那么就:
or if your keys are 1, 2, 3, ... then just:
RuntimeTypeModel.Default.Add(typeof(Order), false)
.Add(memberName, anotherMemberName, ...);
(MetaType
上有无数的选项来控制序列化的所有方面)
(there are a myriad of options on the MetaType
to control all aspects of the serialization)
我认为涵盖了这里的大部分选项!
I think that covers most of the options here!
这篇关于protobuf-net v2 是否需要 DataMember(Order=n) 注释?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!