假设我们有以下代码:
static void Main(string[] args) {
var firstType = new FirstType(new SecondType(2021));
var stream = new MemoryStream();
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(stream, firstType);
stream.Position = 0;
var firstTypeReturned = (FirstType)formatter.Deserialize(stream);
Console.WriteLine(firstTypeReturned.numFromSecondType);
}
[Serializable]
class FirstType : IDeserializationCallback {
public SecondType secondType;
public int numFromSecondType = -1;
public FirstType(SecondType t) {
secondType = t;
}
void IDeserializationCallback.OnDeserialization(Object sender) {
numFromSecondType = secondType.num;
}
}
[Serializable]
class SecondType : IDeserializationCallback {
public int num;
public SecondType(int num) {
this.num = num;
}
void IDeserializationCallback.OnDeserialization(Object sender) {
num = 0;
}
}输出为2021年。
我期望输出为0,因为FirstType包含一个SecondType对象字段,因此为了成功地反序列化FirstType实例,必须先反序列化SecondType,然后将反序列化SecondType意图分配给FirstType的字段。因为SecondType实现了IDeserializationCallback,所以SecondType在其OnDeserialization调用之前不被视为“反序列化完成”。因此,当SecondType完全反序列化时,它的num字段是0,然后将这个SecondType实例传递给FirstType,当FirstType调用它的OnDeserialization时,numFromSecondType应该是0(因为secondType.num应该是0)。
但是不是这样的,看起来FirstType的OnDeserialization方法是先调用的,然后是SecondType的OnDeserialization方法,但不应该是相反的--SecondType的OnDeserialization方法应该先调用,因为它必须先执行这个方法,然后才被认为是完全“反序列化”的。
那么,格式化程序是如此愚蠢,以至于它不知道调用每个对象的OnDeserialization方法的正确顺序吗?
发布于 2021-05-05 13:06:01
,那么格式化程序是如此愚蠢,以至于它不知道调用每个对象的
OnDeserialization方法的正确顺序?
这不是愚蠢的问题;顺序是没有定义的--这是因为在使用BinaryFormatter时很容易获得循环,所以所保证的就是在整个图的常规反序列化代码之后就会发生各种IDeserializationCallback回调--这里的目的是为了使“父”样式对象能够应用任何与“子”数据相关的补丁。如果父级和子级都有IDeserializationCallback回调,那么:这听起来是个坏主意,但我想您可以在字段中跟踪“完成了吗”(老实说,我不会--我只想从内部对象中删除回调)。
https://stackoverflow.com/questions/67401841
复制相似问题