C# 为什么格式化程序是二进制格式化程序,它不能';无法正确处理IDeserializationCallback
假设我们有以下代码:C# 为什么格式化程序是二进制格式化程序,它不能';无法正确处理IDeserializationCallback,c#,.net,C#,.net,假设我们有以下代码: 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.P
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
在调用ondesellization
之前不会被视为“反序列化完成”。因此,当SecondType
被完全反序列化时,其num
字段为0,然后将此SecondType
实例传递给FirstType
,当FirstType
调用其ondeseserialization
时,numFromSecondType
应为0(因为SecondType.num
应为0)
但它不是这样的,它看起来像是先调用FirstType
的OnDeserialization
方法,然后调用SecondType
的OnDeserialization
方法。但是它不应该是另一种方式吗-SecondType
的OnDeserialization
方法应该首先调用,因为它必须先执行这个方法,然后才被认为是完全“反序列化”的
那么,格式化程序是否愚蠢到不知道调用每个对象的方法的正确顺序
那么,格式化程序是否愚蠢到不知道调用每个对象的方法的正确顺序
这不是沉默的问题;顺序未定义-这是因为在使用BinaryFormatter
时很容易获得循环,因此可以保证的是,各种IDeserializationCallback
回调将在整个图形的常规反序列化代码之后发生-此处的目的是为了“父”样式对象可以应用与“子”数据相关的任何修正。如果父级和子级都有IDeserializationCallback
回调,那么:这听起来是个坏主意,但我想您可以在字段中跟踪“完成了吗”(老实说,我不会-我只是从内部对象中删除回调)
那么,格式化程序是否愚蠢到不知道调用每个对象的方法的正确顺序
这不是沉默的问题;顺序未定义-这是因为在使用BinaryFormatter
时很容易获得循环,因此可以保证的是,各种IDeserializationCallback
回调将在整个图形的常规反序列化代码之后发生-此处的目的是为了“父”样式对象可以应用与“子”数据相关的任何修正。如果父对象和子对象都有IDeserializationCallback
回调,那么:这听起来是个坏主意,但我想你可以在一个字段中跟踪“完成了吗”(老实说,我不会-我只是从内部对象中删除回调)。老实说:BinaryFormatter
被认为是过时的,不推荐的,极其危险,;您确定要在此处使用BinaryFormatter
吗?如果您真的这样做了,那么可能值得我们尝试找出答案,但是:在这里选择任何其他序列化程序可能是更好的选择。From:“指示在完成整个对象图的反序列化时通知类”。在调用任何回调之前,对象图被认为是反序列化的。我认为你不能依赖于它们的命名顺序:文档根本没有提到这一点all@amjad其他格式化程序是否可以执行与BinaryFormatter相同或更多的操作并不重要(它们都可以)BinaryFormatter
不仅仅是过时的,它是危险的,而且会从.NET中完全删除。如果您继续使用它,您每年都会遇到更多的错误,因为它的更多组件将从中完全删除。NET@amjad与其要求像BinaryFormatter那样的东西,不如解释一下真正的问题是什么。在反序列化期间,您希望执行哪种处理?你为什么关心订单?这很重要。也许这是一个编码错误(顺序根本不重要)。也许代码试图处理BinaryFormatter的怪癖——让类型句柄反序列化是个坏主意。其他格式化程序有更好的选择,比如自定义converters@amjad对象A引用对象B,对象B引用对象A;现在,你告诉我:“正确”的回调顺序是什么?(var b=new b();bar a=new a{b=b};b.A=A;
坦白说:BinaryFormatter
被认为是过时的、不推荐使用的,而且非常危险;你绝对确定要在这里使用BinaryFormatter
吗?如果你真的这么做,那么可能值得我们尝试找出答案,但是:选择任何其他序列化程序可能是更好的选择m:“指示在完成整个对象图的反序列化时通知类”。在调用任何回调之前,对象图都被认为是反序列化的。我认为您不能依赖调用它们的顺序:文档根本没有提到这一点all@amjad其他格式化程序是否可以执行与BinaryFormatter相同或更多的操作并不重要(它们都可以).BinaryFormatter
不仅仅是过时的,它是危险的,而且会从.NET中完全删除。如果您继续使用它,您每年都会遇到更多的错误,因为它的组件会从.NET中完全删除。NET@amjad与其要求像BinaryFormatter这样的东西,不如解释一下真正的问题是什么割让