Protobuf-Net 似乎重用现有对象而不是创建和分配新对象
Posted
技术标签:
【中文标题】Protobuf-Net 似乎重用现有对象而不是创建和分配新对象【英文标题】:Protobuf-Net seems to reuse existing object instead of creating and assigning a new one 【发布时间】:2014-01-06 17:40:20 【问题描述】:在以下代码中,有 2 个静态状态:初始状态和上次状态。首次创建 Test 类时,它的创建状态为 InitialStatus。可以通过单独的调用 (ChangeStatus) 更改此状态。
当我创建一个 TestClass 对象并更改其状态,然后对该对象进行原型序列化和反序列化时,它看起来会覆盖 InitialStatus 中的值。因此,本质上,Protobuf 似乎在反序列化数据时重用现有对象,如果它可用的话。 (但如果对象为空,它不会那样做)。有什么方法可以自定义此行为,以便在反序列化后重建对象而不是重用现有变量?
[ProtoContract]
public class Status
private static Status _initialStatus;
public static Status InitialStatus
get
if (_initialStatus == null)
_initialStatus = new StatusStatusId=-1;
return _initialStatus;
private static Status _lastStatus;
public static Status LastStatus
get
if (_lastStatus == null)
_lastStatus = new StatusStatusId=-2;
return _lastStatus;
[ProtoMember(101)]
public int StatusIdget; private set;
[ProtoContract]
public class TestClass2
public TestClass2()
Initialize();
private void Initialize()
CurrentStatus = Status.InitialStatus;
[ProtoMember(101)]
public Status CurrentStatusget; 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;
【问题讨论】:
您好,您能提供ProtoUtils
的代码,以便我测试一下吗?
【参考方案1】:
选项:
在 ProtoContractAttribute 上指定 SkipConstructor - 这将防止在对象创建期间初始化该字段 使用反序列化前回调(用适当属性修饰的实例方法)并擦除字段 - 这发生在构造之后但读取数据之前【讨论】:
我应该在我的问题中指定这个,但我不能跳过构造函数。主要是因为在我的实际代码中,构造函数确实做了我不能跳过的额外工作。我希望不使用回调。 @RajRao 我个人仍然会使用跳过的构造函数和回调的组合(准确运行所需的代码) - 但是自定义工厂怎么样?我没有提到的第三个选项是您可以让 protobuf-net 使用静态方法来创建实例,然后可以按照您喜欢的任何方式对其进行初始化以上是关于Protobuf-Net 似乎重用现有对象而不是创建和分配新对象的主要内容,如果未能解决你的问题,请参考以下文章
我可以重复使用对象实例来避免使用 protobuf-net 进行分配吗?
protobuf-net 是不是适合序列化任意对象/域模型?
Automapper - 如何重用对象而不是创建新对象(此对象在列表中)
将 protobuf-net RuntimeTypeModel 编译为 C#,而不是 DLL