使用带有 protobuf-net 异常的代理对 List<T> 进行序列化
Posted
技术标签:
【中文标题】使用带有 protobuf-net 异常的代理对 List<T> 进行序列化【英文标题】:Serializing List<T> using a surrogate with protobuf-net exception 【发布时间】:2013-02-10 09:23:22 【问题描述】:我正在使用 protobuf-net(版本 2.0.0.621)并且在序列化 List 类型时遇到问题,其中 T 是我自己的类(它包含什么并不重要)并且为 T 设置了一个代理项。
代理是这样设置的:
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(MyClass), false).SetSurrogate(typeof(MyClassSurrogate));
我的班级:
public class MyClass
public int Number get; set;
[ProtoContract]
MyClassSurrogate
[ProtoMember(1)]
public int Number get; set;
然后我创建一个 MyClass 实例类型的通用列表,用项目填充它并像这样序列化它:
ProtoBuf.Serializer.Serialize(stream, list);
反序列化时出现问题,在隐式运算符转换中,代理项中不断出现“null”:
static public implicit operator MyClassSurrogate(MyClass myClass)
那么 'myClass' 为空。
如果我删除代理并使用 proto 属性装饰 MyClass,一切正常。
你能告诉我我做错了什么吗?
谢谢。
【问题讨论】:
如果无用则忽略注释,只是想提供帮助,但我从未使用过协议缓冲区。无论如何,问题似乎很基本,这是否为您指明了正确的方向? ***.com/questions/6498438/… 【参考方案1】:向隐式运算符转换添加空检查似乎可以解决问题,即:
public static implicit operator MyClassSurrogate(MyClass myClass)
return myClass != null ? new MyClassSurrogate Number = myClass.Number : null;
隐式运算符最初在反序列化时使用空值调用一次,结果似乎被忽略了。
MyClassSurrogate 的完整实现:
[ProtoContract]
public class MyClassSurrogate
[ProtoMember(1)]
public int Number get; set;
public static implicit operator MyClassSurrogate(MyClass myClass)
return
myClass != null
? new MyClassSurrogate Number = myClass.Number
: null;
public static implicit operator MyClass(MyClassSurrogate myClass)
return new MyClass Number = myClass.Number ;
完整序列化/反序列化示例:
var model = ProtoBuf.Meta.RuntimeTypeModel.Default;
model.Add(typeof(MyClassSurrogate), true);
model.Add(typeof(MyClass), false).SetSurrogate(typeof(MyClassSurrogate));
var stream = new System.IO.MemoryStream();
var list = new List<MyClass>();
for (int x = 0; x < 10; x++) list.Add(new MyClass Number = x );
ProtoBuf.Serializer.Serialize(stream, list);
stream.Seek(0, SeekOrigin.Begin);
var xs = ProtoBuf.Serializer.Deserialize<List<MyClass>>(stream);
foreach (var x in xs) Debug.WriteLine(x.Number);
【讨论】:
【参考方案2】:值 null 经常使用,包括在反序列化期间。您应该能够简单地通过告诉转换运算符将 null 转换为 null 来解决此问题:
if(value == null) return null;
考虑一下,我可能可以安全地添加一个“如果两者都是引用类型,则自动将 null 转换为 null”。
【讨论】:
以上是关于使用带有 protobuf-net 异常的代理对 List<T> 进行序列化的主要内容,如果未能解决你的问题,请参考以下文章