类序列化导致外部库中的stackOverflowException
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了类序列化导致外部库中的stackOverflowException相关的知识,希望对你有一定的参考价值。
我试图序列化/反序列化BindingList到XML文件,但总是得到一个错误:
System.Xml.dll中发生了未处理的“System.StackOverflowException”类型异常
据我所知,它是由于一些无效的引用(get,set,return this)和无限的recurssions引起的。两天浪费没有成功。
数据使用BindingSource和BindingList绑定在一起,也显示在dataGridView中。
我初始化所有可序列化的类:
public Person persons = new Person();
我创建了bindingSources:
BindingSource bsPerson = new BindingSource();
在main函数中,我创建了添加了项的所有BindingLists:
BindingList<Person> persons = new BindingList<Person>()
{
new Person()
{
Surname = "Abc", Phone = "123",
Address = "Street 1",
Email = "some@domain.com",
Car = new BindingList<Car>() { cars[0], cars[1]} }
};
这是我的可序列化类:
[Serializable]
public class Person : BindingList<Person>
{
public string Surname { get; set; }
public string Phone { get; set; }
public string Addres { get; set; }
public string Email { get; set; }
public BindingList<Car> Car { get; set; }
public Person()
{
Car = new BindingList<Car>();
}
}
[Serializable]
public class Car
{
public string Model { get; set; }
public int Mileage { get; set; }
public DateTime ManufactureDate { get; set; }
public int WheelCount { get; set; }
public string FuelType { get; set; }
public int Seats { get; set; }
public GearBox GearBox { get; set; }
public Car self { get { return this; } }
}
[Serializable]
public class GearBox
{
public string Name { get; set; }
public int CountOfTransfers { get; set; }
public string Type { get; set; }
public GearBox self {get {return this;} }
}
[Serializable]
public class ServiceVisits
{
public DateTime ServiceInDate { get; set; }
public DateTime ServiceOutDate { get; set; }
public double Bill { get; set; }
public string EmployeeName { get; set; }
public BindingList<ServiceParts> ServiceParts { get; set; }
public ServiceVisits()
{
ServiceParts = new BindingList<ServiceParts>();
}
public Company Company { get; set; }
public Car Car { get; set; }
}
[Serializable]
public class Company
{
public string Name { get; set; }
public string Phone { get; set; }
public int VatNumber { get; set; }
public string Address { get; set; }
public Company self { get { return this; } }
}
[Serializable]
public class ServiceParts
{
public string Name { get; set; }
public double Price { get; set; }
}
这就是我调用serialize函数的方法:
Serializeri.Serializacija<Person>(persons, path);
这就是我调用deserialize函数的方法:
Serializeri.Deserializacija<Person>(persons, path);
这是包含序列化/反序列化函数的类:
public static class Serializeri
{
public static void Serializacija<T>(this BindingList<T> list, string path)
{
try
{
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "XML Faili (*.xml) | *.xml";
if (sfd.ShowDialog() == DialogResult.OK)
{
XmlSerializer srz = new XmlSerializer(typeof(BindingList<T>));
XmlWriter xw = XmlWriter.Create(sfd.FileName);
srz.Serialize(xw, list);
xw.Flush();
xw.Close();
}
}
catch (IOException)
{
MessageBox.Show("Nevar saglabāt failu, jo to izmanto cits process!", "Kļūda", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
public static void Deserializacija<T>(this BindingList<T> list, string path)
{
try
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "XML Faili (*.xml) | *.xml";
if (ofd.ShowDialog() == DialogResult.OK)
{
XmlSerializer srz = new XmlSerializer(typeof(BindingList<T>));
XmlReader xr = XmlReader.Create(ofd.FileName);
var obj = (BindingList<T>)(srz.Deserialize(xr));
list.Clear();
foreach (var element in obj)
{
list.Add(element);
}
xr.Close();
}
}
catch (IOException)
{
MessageBox.Show("Nevar atvērt failu, jo to izmanto cits process!", "Kļūda", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
如何修复它以便序列化工作?我对界面不是很熟悉,如果我能在这个时候避开它们会很好。
调试后我发现有时数据没有正确添加。它显示在dataGridView中,但实际的BindingList为空(count = 0)。
Person
没有理由成为自己的集合。无论如何你永远不会把它当作自己的集合,所以如果你不把它当成一个就没有损失。当我从BindingList<Person>
中删除基类Person
时,序列化不再无限地递归。
public class Person
{
问题是我在Main函数中定义了BindingList<Person>
和所有其他列表。基本上我的Serialize / Deserialzie函数访问的是类的实例(与BindingLists同名)而不是真正的列表。
我将BindingList<Person> persons;
移动到Main类的开头,它开始工作并保存数据(对功能的修改也很少)。
以上是关于类序列化导致外部库中的stackOverflowException的主要内容,如果未能解决你的问题,请参考以下文章
跨越不同JVM的Java标准库中的SerialVersionUID