Pas marqué comme sérialisable erreur lors de la sérialisation d'une classe

Je sérialise une structure en utilisant BinaryFormatter utilisant ce code:

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 est ma structure, j'appelle cette fonction comme ceci:

SerializableStructure s = new SerializableStructure();
s.NN = NN;
s.SubNNs = SubNNs;
s.inputs = inputs;
SerializeObject(Application.StartupPath + "Save" + txtSave.Text + ".bin", s);

SerializableStructure, et Type de NN,SubNNs et les entrées sont sérialisables. (entrées contient des Points,Rectangles et les listes génériques).

maintenant, quand j'exécute mon code, on me donne cette erreur:

Type ' MainProject.Projet principal "in Assembly", Version = 1.0.0.0, Culture=neutre, PublicKeyToken = null' n'est pas marqué comme serialisable.

pourquoi m'a-t-on donné cette erreur? Main est ma forme, et ces variables sont localisées dans ma forme.

j'ai réussi à sérialisé Type de NN<!--12 et VB.NET mais je ne sais pas pourquoi j'ai cette erreur?

Voici la définition de mon structures:

SerializableStructure:

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

Entrées:

[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 est très grande structure(!).

17
demandé sur Wai Ha Lee 2011-12-24 15:07:10

2 réponses

cela signifie presque alwas que vous avez un événement (ou un autre délégué - peut-être un rappel) quelque part dans votre modèle d'objet, qui essaye d'être sérialisé. Ajouter [Non serialized] à tous les champs de soutien d'événements. Si vous utilisez un champ comme événement (le plus probable), c'est:

[field:NonSerialized]
public event SomeDelegateType SomeEventName;

alternativement: la plupart des autres sérialiseurs ne regardent pas les événements/délégués, et fournissent une meilleure compatibilité de version. Passage à XmlSerializer, JavaScriptSerializer, DataContractSerializer ou protobuf-net (seulement 4 exemples) résoudrait aussi cela par la simple approche de ne pas essayer de le faire (vous n'avez presque jamais l'intention que des événements soient considérés comme faisant partie d'une DTO).

15
répondu Marc Gravell 2011-12-24 11:25:41

le problème est que vous essayez de sérialiser une classe dérivée de Form. La classe de forme est fondamentalement insérialisable. Il a une énorme quantité d'état interne qui dépend fortement de la durée d'exécution. Cela commence avec une propriété évidente comme Handle, une valeur qui est toujours différente. Moins évidentes sont les propriétés comme la taille, dépendant des préférences de l'utilisateur comme la taille de la police pour la légende de fenêtre. Se termine avec tout le texte, l'emplacement et les tailles pour les contrôles, ils sont soumis à localisation. Les chances qu'un objet de forme sérialisé puisse être correctement désérialisé n'importe où à n'importe quel moment pour créer un clone exact de la forme sont nulles.

Microsoft n'a fait aucun os à ce sujet quand ils ont écrit le code, ils ont simplement omis l'attribut [Serialisable] de la déclaration de classe. C'est pourquoi vous obtenez une exception.

vous devrez viser plus bas, écrire votre propre classe pour capturer l'état de votre forme. Et lui donner l'attribut. Vous aurez besoin d'écrire un tas de code qui relie la forme et les propriétés de contrôle à un objet de cette classe, en va-et-vient.

3
répondu Hans Passant 2011-12-24 22:35:39