3 votes

Limites de la sérialisation en C#

Je souhaite mettre en œuvre un modèle général de mémento en C#. Cela fonctionne bien mais j'utilise l'attribut Serializeable() pour faire une copie profonde d'un objet. Mon implémentation utilise des génériques, donc si quelqu'un l'utilise, il doit donner sa classe comme type. Maintenant la classe de l'utilisateur doit avoir l'attribut Serializeable() aussi. Y a-t-il des limitations pour une classe qui utilise Serializeable() ?

En effet :

  1. Y a-t-il des problèmes de performance ?
  2. Est-il possible d'utiliser une interface ?
  3. Est-il possible d'utiliser l'inertie ?
  4. Est-il possible d'utiliser les propriétés automatiques ?

Je ne sais pas comment fonctionne l'attribut et j'ai donc un peu peur de l'utiliser d'une manière aussi globale.

regards

5voto

Marc Gravell Points 482669
  1. pour les petits modèles que vous clonez en mémoire, pas habituellement
  2. sans objet ; lors de l'utilisation de [Serializable] vous utilisez généralement BinaryFormatter - qui examine la les objets eux-mêmes ; peu importe les interfaces qu'ils mettent en œuvre - les interfaces ne sont pas utilisés
  3. oui, pour la même raison - mais tous les types dans le modèle doivent être [Serializable]
  4. oui, pour la même raison ; note : la valeur par défaut BinaryFormatter La mise en œuvre porte sur les champs - elle ne touchera même pas aux propriétés.

Personnellement, j'essaie de conseiller contre BinaryFormatter mais il ne s'agit peut-être pas d'une utilisation déraisonnable. Cependant, il faut veiller à ce qu'il ne soit pas utilisé de manière déraisonnable. Attention, il est facile d'aspirer accidentellement des objets supplémentaires dans le modèle. event s. Notez que c'est une bonne idée de marquer tous les event comme non sérialisés :

[field:NonSerialized]
public event EventHandler Something;

(ou l'appliquer directement au champ s'il s'agit d'un champ explicite). add / remove accesseurs)

Notez également que tout membre comme :

public object Tag {get;set;} // caller-defined

devrait aussi probablement être [field:NonSerialized] .

Personnellement, je préférer un sérialiseur différent, mais : cela fonctionnera souvent. Je dirai cependant : essayez d'éviter persistant la sortie de BinaryFormatter car il est difficile de garantir la compatibilité entre les différentes révisions de votre code.

Je ne sais pas comment fonctionne l'attribut

C'est le cas rien du tout sauf à ajouter un drapeau IL qui dit "au fait, considérez que c'est ok pour être sérialisé" ; en fait, la plupart des sérialiseurs ne regardez même pas ce drapeau - mais BinaryFormatter est l'un des rares qui faire Regardez ce drapeau. Le vrai code ici est BinaryFormatter ce qui est fondamentalement le cas :

  • ai-je déjà vu cet objet ? si oui, ne conservez que la clé
  • de quel type est-il ? est-il [Serializable] ? stocker l'information sur le type
  • invente une nouvelle référence et la stocke en tant qu'identité
  • dispose-t-il d'un sérialiseur personnalisé ? si oui, utilisez-le
  • Quels sont ses champs ? Accédez à chacun d'entre eux à tour de rôle et stockez la paire nom/valeur.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X