我正在使用marc Gravell的
ProtoBuf-net库(r480,net20)来序列化/反序列化包含Dictionary< object,object>的自定义类.在服务器/客户端场景中使用的已知类型(均为C#).
这将使用BinaryFormatter取代我们当前的方法.
作为基础,我遵循这里提出的建议:
protobuf-and-listobject-how-to-serialize-deserialize和 protobuf-and-listobject-how-to-serialize-deserialize.
这将使用BinaryFormatter取代我们当前的方法.
作为基础,我遵循这里提出的建议:
protobuf-and-listobject-how-to-serialize-deserialize和 protobuf-and-listobject-how-to-serialize-deserialize.
目前的方法有一些缺点,我希望更熟悉Protobuf-net的人可以给我一个如何改进它的暗示.
>复制字典< object,object>字典< ProtoObject,ProtoObject>在OnSerialising()调用上.
>添加新类型的维护开销(每个类型都需要ProtoInclude标记和ProtoObject.Create(object obj)中的相应强制转换逻辑)
> ProtoObject必须知道所有必需的类型.这会导致项目之间的循环引用问题,这只能通过更大的项目结构重构来解决.
理想情况下,我想使用RuntimeTypeModel方法,但我不知道如何让客户端知道类型(编译和传输TypeModel dll到客户端?).
同样在第一个主题中,marc Gravell提到即将推出的“运行时可扩展模式”可能会有所帮助,是否有人知道这些模式是否已实现以及它们如何工作?
我非常感谢我得到的任何回复,如果我能澄清更多内容,请告诉我.
无论如何,多亏marc Gravell的神奇图书馆:).
这是代码:
[Serializable] [ProtoContract] public class Attributes : IXmlSerializable,IEnumerable,IEquatable<Attributes>,ICloneable { // Non ProtoBuf-net relevant code was removed private Dictionary<object,object> attributes = new Dictionary<object,object>(); [ProtoMember(1)] private Dictionary<ProtoObject,ProtoObject> protoDictionary; [OnSerializing] public void OnSerializing(StreamingContext context) { this.protoDictionary = new ProtoDictionary(); foreach (var attribute in attributes) { this.protoDictionary.Add(ProtoObject.Create(attribute.Key),ProtoObject.Create(attribute.Value)); } } [OnDeserialized] public void OnDeserialized(StreamingContext context) { if (this.protoDictionary != null) { this.attributes = new SerializableHashtable(); foreach (var o in this.protoDictionary) { this.attributes.Add(o.Key.Value,o.Value.Value); } } } } [ProtoContract] [ProtoInclude(1,typeof(ProtoObject<bool>))] [ProtoInclude(2,typeof(ProtoObject<byte>))] [ProtoInclude(3,typeof(ProtoObject<sbyte>))] [ProtoInclude(4,typeof(ProtoObject<ushort>))] [ProtoInclude(5,typeof(ProtoObject<short>))] [ProtoInclude(6,typeof(ProtoObject<uint>))] [ProtoInclude(7,typeof(ProtoObject<int>))] [ProtoInclude(8,typeof(ProtoObject<ulong>))] [ProtoInclude(9,typeof(ProtoObject<long>))] [ProtoInclude(10,typeof(ProtoObject<float>))] [ProtoInclude(11,typeof(ProtoObject<double>))] [ProtoInclude(12,typeof(ProtoObject<decimal>))] [ProtoInclude(13,typeof(ProtoObject<string>))] [ProtoInclude(20,typeof(ProtoObject<Vector2F>))] [ProtoInclude(21,typeof(ProtoObject<Vector3F>))] [ProtoInclude(22,typeof(ProtoObject<Shape>))] [ProtoInclude(23,typeof(ProtoObject<SharedUser>))] [ProtoInclude(24,typeof(ProtoObject<SharedShip>))] //[ProtoInclude(25,typeof(ProtoObject<IVehicleConfiguration>))] // Requires Steering dll -> cyclic reference [ProtoInclude(26,typeof(ProtoObject<Dronestate>))] [ProtoInclude(27,typeof(ProtoObject<BuffCode>))] [ProtoInclude(28,typeof(ProtoObject<ItemAttribute>))] [ProtoInclude(40,typeof(ProtoObject<List<int>>))] public abstract class ProtoObject { protected ProtoObject() { } // Replaces public static ProtoObject<T> Create<T>(T value) // in order to use the actual type of the object public static ProtoObject Create(object obj) { if (obj is bool) { return new ProtoObject<bool>((bool)obj); } if (obj is byte) { return new ProtoObject<byte>((byte)obj); } // etc. for all required types return null; } public static ProtoObject Create(bool obj) { TypeModel.Add(obj.GetType(),true); return new ProtoObject<bool>(obj); } public static ProtoObject Create(byte obj) { return new ProtoObject<byte>(obj); } // ... public static ProtoObject Create(type obj) -> for all required types public object Value { get { return ValueImpl; } set { ValueImpl = value; } } protected abstract object ValueImpl { get; set; } } [ProtoContract] public sealed class ProtoObject<T> : ProtoObject { public ProtoObject() { } public ProtoObject(T value) { Value = value; } [ProtoMember(1)] public new T Value { get; set; } protected override object ValueImpl { get { return Value; } set { Value = (T)value; } } public override string ToString() { return Value.ToString(); } }
解决方法
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。