是否应该支持序列化PropertyInfo?如果没有,最好的解决方法是什么?我知道可以序列化类型(支持),然后通过其属性查找属性 - 想象查找可能很昂贵。
P.S。 PropertyInfo用于实现类似于DataLoadOptions.LoadWith http://msdn.microsoft.com/en-us/library/bb548760.aspx的功能。
using System.IO;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using ProtoBuf;
[ProtoContract]
public class A
{
[ProtoMember(1)]
public PropertyInfo Property { get; set; }
}
[TestClass]
public class UnitTest
{
[TestMethod]
public void TestMethod1()
{
var value = new A { Property = typeof(string).GetProperty("Length") };
using (var stream = new MemoryStream())
{
// Raises InvalidOperationException
// "No serializer defined for type: System.Reflection.PropertyInfo"
Serializer.Serialize(stream, value);
}
}
}
引发InvalidOperationException
时调用堆栈:
protobuf-net.dll!ProtoBuf.Meta.ValueMember.BuildSerializer() Line 316 C#
protobuf-net.dll!ProtoBuf.Meta.ValueMember.Serializer.get() Line 188 + 0x24 bytes C#
protobuf-net.dll!ProtoBuf.Meta.MetaType.BuildSerializer() Line 421 + 0x1f bytes C#
protobuf-net.dll!ProtoBuf.Meta.MetaType.Serializer.get() Line 344 + 0xe bytes C#
protobuf-net.dll!ProtoBuf.Meta.RuntimeTypeModel.Serialize(int key, object value, ProtoBuf.ProtoWriter dest) Line 592 + 0x44 bytes C#
protobuf-net.dll!ProtoBuf.Meta.TypeModel.SerializeCore(ProtoBuf.ProtoWriter writer, object value) Line 178 + 0x14 bytes C#
protobuf-net.dll!ProtoBuf.Meta.TypeModel.Serialize(System.IO.Stream dest, object value, ProtoBuf.SerializationContext context) Line 209 + 0xe bytes C#
protobuf-net.dll!ProtoBuf.Meta.TypeModel.Serialize(System.IO.Stream dest, object value) Line 193 + 0x10 bytes C#
protobuf-net.dll!ProtoBuf.Serializer.Serialize<TestProtoBufNet.A>(System.IO.Stream destination, TestProtoBufNet.A instance) Line 88 + 0x18 bytes C#
TestProtoBufNet.dll!TestProtoBufNet.UnitTest.TestMethod1() Line 24 + 0x10 bytes C#
答案 0 :(得分:2)
要添加@ikh已经说过的内容,不,这不是受支持的类型。当我提到标准BCL类型时,我说的是通用数据类型,而不是反射类型。 protobuf和protobuf-net的整个要点是以数据为中心,但PropertyInfo
等是实现,而不是数据。实际上,WinRT对于PropertyInfo
应该有多少信息有一个非常不同的想法。
然而!如果您决定对其进行序列化,请注意Type
支持IIRC。所以你可以通过代理人这样做(完全未经测试,我在iPad上这里!):
[ProtoContract]
public class PropertyInfoSurrogate {
[ProtoMember(1)]
public Type Type { get; set; }
[ProtoMember(2)]
public string Name { get; set; }
public static operator implicit PropertyInfoSurrogate(PropertyInfo value) {
if(value == null) return null;
return new PropertyInfoSurrogate {
Type = value.DeclaringType, Name = value.Name
};
}
public static operator implicit PropertyInfo(PropertyInfoSurrogate value) {
if(value == null) return null;
return value.Type.GetProperty(value.Name);
}
}
然后,到你的模特:
model.Add(typeof(PropertyInfo), false)
.SetSurrogate(typeof(PropertyInfoSurrogate));
重点:完全未经测试,但之类应该有效。让我知道你是怎么过的。
答案 1 :(得分:1)
不幸的是,看起来PropertyInfo
不能被protobuf-net序列化。要序列化其中的数据,您可能必须创建一个单独的ProtoContract
类来存储PropertyInfo
的相关位,并使用它。
具体来说,通过源代码阅读protobuf-net如何找到复杂类型(here和here)的序列化器,看起来protobuf只能用于{{1 - 类似属性,特别是以下任何属性:
[DataContract]
,[DataContract]
,[XmlType]
。并不会与他人合作。
一个简单的实验证实了这一点。以下代码将无异常运行,但如果[ProtoContract]
和[DataContract]
被注释掉,那么我会得到与您相同的异常:
[DataMember]