我使用此代码使用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
和输入都是可序列化的。 (输入包含一些Points
,Rectangles
和通用列表。
现在,当我运行我的代码时,我收到了这个错误:
在Assembly'MainProject中输入'MainProject.Main',Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'未标记为可序列化。
为什么我会收到此错误? Main是我的表单,这些变量位于我的表单中。
我已经使用NN
和VB.NET成功序列化MemoryStream
类型,但我不知道为什么会出现此错误?
以下是我的结构的定义:
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
是一个非常大的结构(!)。
答案 0 :(得分:15)
这几乎意味着您在对象模型中的某个地方有一个事件(或其他委托 - 可能是一个回调),它正在尝试序列化。将[NonSerialized]添加到任何事件备份字段。如果您正在使用类似字段的事件(最有可能的类型),则为:
[field:NonSerialized]
public event SomeDelegateType SomeEventName;
或者:大多数其他序列化程序不查看事件/委托,并提供更好的版本兼容性。切换到XmlSerializer,JavaScriptSerializer,DataContractSerializer或protobuf-net(只有4个例子)也可以通过不尝试这样做的简单方法解决这个问题(你几乎从不打算将事件视为DTO的一部分)。
答案 1 :(得分:4)
问题是您正在尝试序列化从Form派生的类。 Form类从根本上是不可序的。它具有大量与运行时相关的内部状态。这开始于一个明显的属性,如Handle,一个总是不同的值。不太明显的是像Size这样的属性,取决于用户偏好,例如窗口标题的字体大小。结束控件的所有文本,位置和大小,它们受本地化的影响。序列化Form对象可以随时在任何地方正确反序列化以创建表单的精确克隆的几率为零。
微软在编写代码时没有对它进行任何改动,他们只是省略了类声明中的[Serializable]属性。这就是你得到例外的原因。
你必须瞄准更低,写自己的课来捕捉你的形式的状态。并赋予它属性。您需要编写一堆代码,在表单和控件属性之间映射,来回传递该类的对象。