我正在使用以下代码使用
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
和通用列表)。
现在,当我运行代码时,出现以下错误:
在程序集“MainProject,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”中键入“MainProject.Main”未标记为可序列化。
为什么我会收到此错误? Main是我的表单,这些变量位于我的表单中。
我已经使用
NN
和 VB.NET 成功序列化了 MemoryStream
的类型,但我不知道为什么会收到此错误?
这是我的结构的定义:
可序列化结构:
[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 这样明显的属性,它的值总是不同的。不太明显的是“大小”等属性,它取决于用户偏好,例如窗口标题的字体大小。以控件的所有文本、位置和大小结束,它们都需要本地化。序列化的 Form 对象可以随时随地正确反序列化以创建表单的精确克隆的可能性为零。
微软在编写代码时毫不掩饰这一点,他们只是从类声明中省略了 [Serializable] 属性。这就是为什么你会得到例外。
您必须降低目标,编写自己的类来捕获表单的状态。并赋予它属性。您需要编写一堆代码,在表单和控件属性之间来回映射到该类的对象。否则与模型和视图分层的通用原则高度兼容。