我一直在寻找类似这样的东西,但似乎无法收集到关于如何去做的足够信息。
我基本上在寻找类似于每次反序列化字段时发生的回调的东西。在我们的例子中,我们将使用该回调来修改分配给对象的实际值,具体取决于原始字节流上存在的某个标志(不同的属性)。
例如,假设我们想要从缓存中的本地对象中清除某些值。我们不能将它设置为null以清除它,因为当我们反序列化它时,该字段将不会被发送。我们可以发送一个要清除的字段编号列表,并在反序列化时检查当前正在解析的字段编号是否在我们的清除字段集内。
最好的方法是修改反序列化的工作方式,或者至少在它发生之前或之后能够挂钩? (即,有一个自定义的“hasfield”逻辑)。
我知道[OnDeserializedAttribute]和[OnDeserializingAttribute],但这些方法只返回一个上下文,每个对象只有一次。
提前感谢您的帮助。
可能的解决方案
在通过源头挖掘了一下之后,终于在主题中找到了一些亮点。 缺点是,据我所知,如果您使用此解决方案,您将无法在类中使用[ProtoMember]标签。 这也是仅限v2的解决方案(我相信)。
如果我们在运行时编译序列化程序,我们可以为我们需要的每个字段使用“SetSpecified”方法。这样,无论何时设置给定字段(在反序列化期间)或检索(在序列化期间),我们都可以分配要调用的实例方法。我很想知道是否有一个属性来分配这些方法。
以下是我们的所作所为:
static protected void InitSerializer(Type type) {
RuntimeTypeModel model = RuntimeTypeModel.Default;
MetaType metaType = model.Add(type, true);
ValueMember nameField = metaType.AddField(1, "name");
MethodInfo setSpecified = type.GetMethod("SetNameSpecified", BindingFlags.Instance | BindingFlags.NonPublic);
MethodInfo getSpecified = type.GetMethod("GetNameSpecified", BindingFlags.Instance | BindingFlags.NonPublic);
nameField.SetSpecified(getSpecified, setSpecified);
}
#region Serialization Callbacks
protected bool GetNameSpecified() {
Debug.Log ("Get Name Specified");
bool isNameSpecified = false;
// Your logic here
return isNameSpecified;
}
protected void SetNameSpecified(bool specified) {
Debug.Log ("Set Name Specified");
}
#endregion