C# 使用ISerializationSubrogate时反序列化自引用对象时引发异常
尝试反序列化自引用对象时抛出异常 System.Runtime.Serialization.SerializationException:“链接地址信息中引用了ID为1的对象,但该对象不存在。” 这是我的代码:C# 使用ISerializationSubrogate时反序列化自引用对象时引发异常,c#,.net,serialization,binaryformatter,binary-serialization,C#,.net,Serialization,Binaryformatter,Binary Serialization,尝试反序列化自引用对象时抛出异常 System.Runtime.Serialization.SerializationException:“链接地址信息中引用了ID为1的对象,但该对象不存在。” 这是我的代码: class MySerializationSurrogate : ISerializationSurrogate { public void GetObjectData(object obj, SerializationInfo info, StreamingContext co
class MySerializationSurrogate : ISerializationSurrogate {
public void GetObjectData(object obj, SerializationInfo info, StreamingContext context) {
Console.WriteLine("MySerializationSurrogate.GetObjectData()");
}
public object SetObjectData(object obj, SerializationInfo info, StreamingContext context, ISurrogateSelector selector) {
Console.WriteLine("MySerializationSurrogate.SetObjectData()");
var it = info.GetEnumerator();
while (it.MoveNext()) {
Console.WriteLine($"{it.ObjectType} {it.Name} {it.Value}");
}
return obj;
}
}
[Serializable]
class Test {
int prop { get; set; } = 123321;
Test me { get; set; }
public Test() { me = this; }
}
class Program {
static void Save() {
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = new FileStream("E:\\a.txt", FileMode.Create);
Test ch = new Test();
bf.Serialize(fs, ch);
fs.Close();
}
static void Read() {
BinaryFormatter bf = new BinaryFormatter();
SurrogateSelector mss = new SurrogateSelector();
mss.AddSurrogate(typeof(Test), bf.Context, new MySerializationSurrogate());
bf.SurrogateSelector = mss;
FileStream fs = new FileStream("E:\\a.txt", FileMode.Open);
object ch = bf.Deserialize(fs);
fs.Close();
}
static void Main(string[] args) {
Save();
Read();
Console.ReadLine();
}
}
我的控制台中没有任何输出,因此我认为SetObjectData()
和GetObjectData()
没有被调用
如果我删除mss.AddSurrogate(typeof(Test)、bf.Context、new MySerializationSurrogate())代码>代码将成功运行
如果我删除Test.me
,代码将成功运行
我试图找出问题所在,所以我创建了一个循环引用,如下所示:
a、 p=b;b、 p=a;序列化(fs,a)
然后反序列化,没有任何异常。因此,支持循环引用
似乎当您使用用户定义的代理并尝试反序列化具有自指针的对象时,将引发异常
甚至你的代理人也没有打电话
那怎么了
我唯一能做到这一点的方法是使用sentinel手动编码自参考有效载荷:
const string Self=“Self”;
public void GetObjectData(对象对象对象、序列化信息、StreamingContext上下文)
{
var检验=(检验)obj;
信息附加值(“prop”,test.prop);
如果(test.me为null){}
else if(ReferenceEquals(test.me,test))
{
信息增值(“我”,自我);
}
其他的
{
信息增值(“me”,test.me);
}
}
公共对象SetObjectData(对象对象对象、序列化信息、StreamingContext上下文、iUrrogateSelector选择器)
{
var it=info.GetEnumerator();
var检验=(检验)obj;
while(it.MoveNext())
{
开关(it.Name)
{
案例“道具”:
test.prop=(int)it.Value;
打破
案例“我”:
开关(it.Value)
{
当s==Self时的大小写字符串s:
test.me=测试;
打破
案例测试t:
test.me=t;
打破
}
打破
}
}
返回obj;
}
我想运行你的代码,这样我就可以看到与你看到的相同的东西-你有mySerializationSubrogate
代码吗?另外,我不是想“成为那个人”,但是:我真的,真的,真的建议不要使用BinaryFormatter
,在任何情况下:mySerializationSubrogate
位于代码块的顶部,您只需要添加一些导入@MarcGravelMaybe例外信息有点不同,我用谷歌翻译把它翻译成英语;我一定是向下滚动了!看,如果您将代理配置代码从Read
复制到Save
,一切正常-这就是这里缺少的吗?是的,它确实有效,谢谢。但为什么会出现这个问题呢?如果不是我的错,BinaryFormatter
中是否存在错误?但这是怎么回事BinaryFormatter
在.Net中已经存在这么多年了@维克托12369我不认为这是一个错误;更多的情况是:如果你要承担控制权,你需要承担控制权,这包括自参考数据的问题;这里可能有一种方法可以将IObjectReference
破解到混合中,这样它就可以迅速地将一些东西放入图形中。。。让我看一眼(编辑:不,也不能让它工作)