序列化类时未标记为可序列化错误

Mah*_*asi 20 c# serialization stream

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();
}
Run Code Online (Sandbox Code Playgroud)

objectToSerialize是我的结构,我正在调用这个函数:

SerializableStructure s = new SerializableStructure();
s.NN = NN;
s.SubNNs = SubNNs;
s.inputs = inputs;
SerializeObject(Application.StartupPath + "\\Save\\" + txtSave.Text + ".bin", s);
Run Code Online (Sandbox Code Playgroud)

其中SerializableStructure,和类型NN,SubNNs并输入是序列化的.(输入包含一些Points,Rectangles和通用的列表).

现在,当我运行我的代码时,我收到了这个错误:

在Assembly'MainProject中输入'MainProject.Main',Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null'未标记为可序列化.

为什么我会收到这个错误?Main是我的表单,这些变量位于我的表单中.

我已经成功序列化的类型NNMemoryStream和VB.NET,但我不知道为什么我得到这个错误?

这是我的结构的定义:

SerializableStructure:

[Serializable()]
public class SerializableStructure
{
    public List<Inputs> inputs = new List<Inputs>();
    public NeuralNetwork NN;
    public NeuralNetwork[] SubNNs;
}
Run Code Online (Sandbox Code Playgroud)

输入:

[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>();
    }
}
Run Code Online (Sandbox Code Playgroud)

也是NN非常大的结构(!).

Mar*_*ell 16

这几乎意味着你在对象模型中的某个地方有一个事件(或其他委托 - 可能是一个回调),它试图被序列化.将[NonSerialized]添加到任何事件备份字段.如果您正在使用类似字段的事件(最可能的类型),这是:

[field:NonSerialized]
public event SomeDelegateType SomeEventName;
Run Code Online (Sandbox Code Playgroud)

或者:大多数其他序列化程序不查看事件/委托,并提供更好的版本兼容性.切换到XmlSerializer,JavaScriptSerializer,DataContractSerializer或protobuf-net(只有4个例子)也可以通过不尝试这样做的简单方法来解决这个问题(你几乎从不打算将事件视为DTO的一部分).


Han*_*ant 6

问题是您正在尝试序列化从 Form 派生的类。Form 类基本上是不可序列化的。它具有大量高度依赖于运行时的内部状态。首先是像 Handle 这样明显的属性,它的值总是不同的。不太明显的是“大小”等属性,它取决于用户偏好,例如窗口标题的字体大小。以控件的所有文本、位置和大小结束,它们都需要本地化。序列化的 Form 对象可以随时随地正确反序列化以创建表单的精确克隆的可能性为零。

微软在编写代码时毫不掩饰这一点,他们只是从类声明中省略了 [Serializable] 属性。这就是为什么你会得到例外。

您必须降低目标,编写自己的类来捕获表单的状态。并赋予它属性。您需要编写一堆代码,在表单和控件属性之间来回映射到该类的对象。否则与模型和视图分层的通用原则高度兼容。