我正在使用BinaryFormatter
序列化一个结构,使用以下代码:
private void SerializeObject(string filename, SerializableStructure objectToSerialize)
{
Stream stream = File.Open(filename, FileMode.Create);
BinaryFormatter bFormatter = new BinaryFormatter();
bFormatter.Serialize(stream, objectToSerialize);
stream.Close();
}
哪个objectToSerialize
是我的结构,我这样调用这个函数:
SerializableStructure s = new SerializableStructure();
s.NN = NN;
s.SubNNs = SubNNs;
s.inputs = inputs;
SerializeObject(Application.StartupPath + "\Save\" + txtSave.Text + ".bin", s);
哪一个SerializableStructure
、NN
、SubNNs
的Type和输入是可串行化的。(输入包含一些Points
, Rectangles
和通用列表)。
现在,当我运行我的代码,我得到这个错误:
MainProject类型"。Main' in Assembly 'MainProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'未标记为可序列化的。
为什么我得到这个错误?Main是我的表单,这些变量位于我的表单中。
我已经成功地用MemoryStream
和VB序列化了NN
的类型。. NET,但我不知道为什么我得到这个错误?下面是我的结构的定义:
SerializableStructure:
[Serializable()]
public class SerializableStructure
{
public List<Inputs> inputs = new List<Inputs>();
public NeuralNetwork NN;
public NeuralNetwork[] SubNNs;
}
输入:[Serializable()]
public class Inputs
{
public string XPath { get; set; }
public string YPath { get; set; }
public string ImagePath { get; set; }
public string CharName { get; set; }
public string CharBaseName { get; set; }
public List<double> x { get; set; }
public List<double> y { get; set; }
public List<double> DotsX { get; set; }
public List<double> DotsY { get; set; }
public List<Point> GravityCenters { get; set; }
public List<Rectangle> Bounds { get; set; }
public override string ToString()
{
return CharName;
}
public Inputs(string xPath, string yPath, string imagePath, string charName, string charBaseName)
{
XPath = xPath;
YPath = yPath;
ImagePath = imagePath;
CharName = charName;
CharBaseName = charBaseName;
x = new List<double>();
y = new List<double>();
GravityCenters = new List<Point>();
Bounds = new List<Rectangle>();
}
}
另外NN
是非常大的结构(!)。
这几乎总是意味着您在对象模型中的某个地方有一个事件(或其他委托-可能是回调),它试图被序列化。在任何事件支持字段中添加[NonSerialized]。如果您正在使用类似字段的事件(最有可能的类型),这是:
[field:NonSerialized]
public event SomeDelegateType SomeEventName;
或者:大多数其他序列化器不查看事件/委托,并提供更好的版本兼容性。切换到XmlSerializer、JavaScriptSerializer、DataContractSerializer或protobuf-net(仅举4个例子)也可以通过不尝试这样做的简单方法来解决这个问题(您几乎从不打算将事件视为DTO的一部分)。
问题是您正在尝试序列化从Form派生的类。Form类基本上是不可序列化的。它有大量高度依赖于运行时的内部状态。它从一个明显的属性开始,比如Handle,一个总是不同的值。像Size这样的属性就不那么明显了,它取决于用户的偏好,比如窗口标题的字体大小。以控件的所有文本、位置和大小结束,它们受制于本地化。序列化的Form对象可以在任何时间、任何地点正确地反序列化,从而创建一个完全相同的Form克隆的可能性为零。
Microsoft在编写代码时对此毫不犹豫,他们只是从类声明中省略了[Serializable]属性。这就是为什么会出现异常。
你将不得不降低目标,编写自己的类来捕获表单的状态。然后给它一个属性。您需要编写一堆代码,在表单和控件属性之间来回映射到该类的对象。