Protobuf-Net似乎重用现有对象而不是创建和分配新对象

时间:2014-01-06 17:40:20

标签: c# deserialization protobuf-net

在以下代码中,有2个静态状态:初始状态和上次状态。首次创建Test类时,将创建状态为InitialStatus的Test类。单独调用(ChangeStatus)可以更改此状态。

当我创建TestClass的对象并更改其状态然后对该对象进行proto序列化和反序列化时,它看起来像覆盖了InitialStatus中的值。所以从本质上讲,Protobuf似乎重用了一个现有的对象,如果它在反序列化数据时可用。 (但是如果对象为null,则不会这样做)。有没有什么方法可以自定义这种行为,以便在反序列化后,重构对象而不是重用现有的变量?

[ProtoContract]
public class Status
{
    private static Status _initialStatus;
    public static Status InitialStatus
    {
        get{
            if (_initialStatus == null)
            {
                _initialStatus = new Status{StatusId=-1};
            }
            return _initialStatus;
        }
    }

    private static Status _lastStatus;
    public static Status LastStatus
    {
        get{
            if (_lastStatus == null)
            {
                _lastStatus = new Status{StatusId=-2};
            }
            return _lastStatus;
        }
    }

    [ProtoMember(101)]
    public int StatusId{get; private set;}
}

[ProtoContract]
public class TestClass2
{
    public TestClass2()
    {
        Initialize();
    }

    private void Initialize()
    {
        CurrentStatus = Status.InitialStatus;
    }

    [ProtoMember(101)]
    public Status CurrentStatus{get; private set;}

    public void ChangeStatus(Status newStatus)
    {
        CurrentStatus = newStatus;
    }
}


void Main()
{
    TestClass2 test = new TestClass2();

    test.ChangeStatus(Status.LastStatus);


    string serializedTest = ProtoUtils.Serialize(test);
    TestClass2 testDeserialized = ProtoUtils.Deserialize<TestClass2>(serializedTest);

    Debug.Assert(Status.InitialStatus.StatusId == -1, "Initial Status has changed");
    Debug.Assert(Status.LastStatus.StatusId == -2, "Last Status has changed");
}


public static class ProtoUtils
{
    public static string Serialize(Object o)
    {
        String result = String.Empty;

        using (MemoryStream stream = new MemoryStream())
        {
            Serializer.Serialize(stream, o);

            result = Convert.ToBase64String(stream.ToArray());
        }
        result.Dump();
        return result;
    }

    public static T Deserialize<T>(string data)
    {
        T result = default(T);

        if (data != null)
        {
            byte[] dataBytes = Convert.FromBase64String(data);

            using (Stream stream = new MemoryStream(dataBytes))
            {
                result = Serializer.Deserialize<T>(stream);
            }

        }

        return result;
    }
}

1 个答案:

答案 0 :(得分:1)

选项:

  • 在ProtoContractAttribute上指定SkipConstructor - 这将阻止在对象创建期间初始化字段
  • 使用before-deserialization回调(用适当的属性修饰的实例方法)并擦除字段 - 这在构造之后但在读取数据之前发生