C# 是否可以在Windows Phone 7/8上使用protobuf net序列化/反序列化不可变类型?

C# 是否可以在Windows Phone 7/8上使用protobuf net序列化/反序列化不可变类型?,c#,windows-phone-7,windows-phone,immutability,protobuf-net,C#,Windows Phone 7,Windows Phone,Immutability,Protobuf Net,是否可以在Windows Phone 7/8上使用protobuf net对类型进行序列化/反序列化? 我尝试了下面的代码,似乎不支持跳过构造函数(即UseConstructor=false),因此我创建了一个无参数构造函数,但反序列化失败,出现“尝试访问方法失败:Wp7Tests.ImmutablePoint.set_X(System.Double)” 公共类不可变点 { 公共双X{get;私有集;} 公共双Y{get;私有集;} 公共不可变点(){} 公共不可变点(双x,双y) { X=X;

是否可以在Windows Phone 7/8上使用protobuf net对类型进行序列化/反序列化?
我尝试了下面的代码,似乎不支持跳过构造函数(即UseConstructor=false),因此我创建了一个无参数构造函数,但反序列化失败,出现“尝试访问方法失败:Wp7Tests.ImmutablePoint.set_X(System.Double)”

公共类不可变点
{
公共双X{get;私有集;}
公共双Y{get;私有集;}
公共不可变点(){}
公共不可变点(双x,双y)
{
X=X;
Y=Y;
}
}
公共子测试()
{
ImmutablePoint pt=新的ImmutablePoint(1,2);
var model=TypeModel.Create();
var ptType=model.Add(typeof(ImmutablePoint),false);
ptType.AddField(1,“X”);
pType.AddField(2,“Y”);
IsolatedStorageFile store=IsolatedStorageFile.GetUserStoreForApplication();
使用(var stream1=new-IsolatedStorageFileStream(“test.bin”,FileMode.Create,store))
{
尝试
{
序列化(stream1,pt);
}
捕获(例外e)
{                    
Debugger.Break();
}
}
常数双ε=0.001;
使用(var stream1=新的隔离存储文件流(“test.bin”,FileMode.Open,store))
{
尝试
{
ImmutablePoint ptDeSer=(ImmutablePoint)模型。反序列化(stream1,null,typeof(ImmutablePoint));
Assert(Math.Abs(pt.X-ptDeSer.X)
这在Windows Phone上是不可能的。反序列化程序无法访问setter,使用反射访问私有成员会导致Windows Phone上出现MemberAccessException。我能想到的唯一办法就是创建一个用于序列化的包装器,然后调用ImmutablePoint的构造函数。不过这有点混乱,因为包装器类需要X和Y的公共读写属性

您还可以考虑使用InternalsVisibleTo属性来允许序列化程序访问属性(假设您将setter从private更改为internal)。但是仍然很混乱…

你可以使用代理;这里我用属性来装饰它,但也可以手动配置:

[ProtoContract]
public class MutablePoint {
    [ProtoMember(1)] public double X { get; set; }
    [ProtoMember(2)] public double Y { get; set; }

    public static implicit operator MutablePoint(ImmutablePoint value) {
        return value == null ? null : new MutablePoint {X=value.X, Y=value.Y};
    }
    public static implicit operator ImmutablePoint(MutablePoint value) {
        return value == null ? null : new ImmutablePoint(value.X, value.Y);
    }
}
然后告诉模型在看到
不可变点时使用此选项:

var model = TypeModel.Create();
model.Add(typeof(MutablePoint), true);
model.Add(typeof(ImmutablePoint), false).SetSurrogate(typeof(MutablePoint));
序列化程序将根据需要使用运算符在它们之间切换。序列化程序将使用
隐式
显式
自定义转换运算符

编辑: 像这样反序列化

ImmutablePoint ptDeSer = (ImmutablePoint)model.Deserialize(stream1, null, typeof(ImmutablePoint));

我猜是这样的:(.我想我可能会添加一个接口,比如ISerializablePoint,它公开了X,Y属性,然后在类上显式地实现它们。这不是一个理想的解决方案,但我认为它传达了意图,并且隐藏了class@DavidHayes还有一种更优雅的方式……答案补充道
ImmutablePoint ptDeSer = (ImmutablePoint)model.Deserialize(stream1, null, typeof(ImmutablePoint));