web-dev-qa-db-fra.com

C # sérialiser un membre de classe privé

class Person
{
    public string m_name;
    private int m_age; // << how do I serialize the darn little rat?
}

Une question simple mais qui semble être un gros désastre lorsque vous essayez d'y répondre.
Tout le monde suggère d’utiliser le getter/setter public, mais mon application est trop grosse et créer un getter/setter pour chaque membre ne ferait que causer des problèmes de maintenabilité.

Suis-je obligé de créer ici une sérialisation personnalisée ou existe-t-il un attribut magique pour ces membres?
Comment sérialiser des membres de classe privés?

Edit # 1:
Ok tout le monde, désolé pour le manque de clarté, j'étais un peu contrarié quand j'ai écrit cette question, c'était plusieurs heures après avoir essayé de trouver la solution.
Quoi qu'il en soit, voici d'autres faits:
1. J'essaie de sérialiser XML cette classe. _ {J'utilise actuellement System.Xml.Serialization.XmlSerializer.
2. Je suis sérialisant en XML pour avoir la compatibilité de version}, qui, autant que je sache, le binaire ne m'offre pas cela.
3.J'espérais qu'il y ait un certain attribut like:

class Person
{
    public string m_name;
    [SerializeThat(ElementName="Age")]
    private int m_age; // << how do I serialize the darn little rat?
}

OU (suite des faits # 3) un attribut qui va dans la classe qui ressemblerait à ceci:

[Serializable(DoPrivate = true, DoProtected = true)]
class Person
{
    public string m_name;
    private int m_age; // << how do I serialize the darn little rat?
}

Maintenant, que puis-je faire pour y parvenir?

31
Poni

Dans l’hypothèse d’une faute de frappe, je voudrais vous rediriger vers cet article SO où la solution consiste à utiliser un DataContractSerializer à la place.

17
Brad Christie

Si vous utilisez BinaryFormatter, les parties privées de votre classe seront utilisées.

Marquez chaque classe avec [Serializable] ou vous n'irez pas loin ...

Regardez aussi ceci: Pourquoi l'attribut Serializable est requis pour qu'un objet soit sérialisé

Puisque vous avez besoin de XML, vous pouvez peut-être vous débrouiller avec SoapFormatter. Voir this .

Compatibilité de la version Apropos: J'utilise BinaryFormatter et je n'ai aucun problème avec les mises à niveau de schéma. Essayez-le s'il vous plaît: vous pouvez gérer vous-même les modifications de schéma, nous remplaçons simplement les pointeurs nuls laissés par la variable Deserialize par les constructions par défaut appropriées. Si vous n'avez pas vraiment besoin des fonctionnalités fournies par XML, passez au binaire - vous ne regarderez jamais en arrière.

En outre, un autre EDIT:

BF résoudra facilement toutes vos références multiples afin de ne pas créer plusieurs instances de la même référence à plusieurs reprises. Je suppose que vous n’obtiendrez pas cela avec XmlSerializer - il est évident qu’il n’ya pas d’endroit où stocker ces informations.

Exemple:

class Data
{
    int a;
}

class ManyData
{
    Data d1;
    Data d2;
}

...

ManyData md=new ManyData();
md.d1=new Data();
md.d2=md.d1;

Essayez de sérialiser/désérialiser md avec plusieurs alternatives ...

8
Daniel Mošmondor

Je ne sais pas si vous pouvez utiliser DataContract . Mais avec cela, vous pouvez écrire:

[DataContract]
class Person
{
    [DataMember]
    public string m_name;

    [DataMember]
    private int m_age;
}

DataContract présente l'avantage de pouvoir sérialiser les champs privés et que votre classe n'a pas besoin de constructeur par défaut.

7
Oliver

Quel sérialiseur vous a mangé actuellement? Presque tous devraient travailler avec ça. Mais les champs publics * est * une mauvaise idée. XmlSerializer et JavaScriptSerializer ignoreront les membres privés. DataContractSerializer et protobuf-net can traitent avec des membres privés. BinaryFormatter traite les champs fields (public ou privé), mais ce n’est pas une bonne idée de l’OMI pour de nombreuses raisons.

5
Marc Gravell
2
Master Morality

Utilisez les champs d'interface et de contrôle IXmlSerializable que vous souhaitez sérialiser:

public interface IXmlSerializable
{
    XmlSchema GetSchema();
    void ReadXml(XmlReader reader);
    void WriteXml(XmlWriter writer);
}
0
Stas BZ
0
Sid C