Résoudre les problèmes de sérialisation sur les évènements des classes

Soyez le premier à donner votre avis sur cette source.

Snippet vu 7 211 fois - Téléchargée 23 fois

Contenu du snippet

Ceux qui ont déjà programmé des classes pour une appli windows savent peut-être de quoi je veux parler.
Imaginons que j'aie une classe "Compte" et une classe "Opération" pour une appli bancaire.
Ces deux classes sont sérialisables.

Je pose un évènement sur l'objet "Operation" qui se déclenche lorsque le solde de celle-ci change.
J'aimerais récupérer cet évènement à la fois dans ma classe "Compte" et dans mon interface graphique.
Jusque-là, pas de problème, sauf si je tente de sérialiser la classe "Operation".
En effet, le sérialiseur regarde toutes les propriétés de la classe "Operation", découvre l'évènement, puis tente de sérialiser l'objet "Compte" (pas de problème), ainsi que les objets de mon interface graphique qui récupèrent cet évènement. Et là : problème ! Ceux-ci ne sont peut-être pas sérialisables...
Comment faire ?
Pour résoudre ce problème, il vaut mieux définir deux évènements :
- Un qui sera marqué comme internal, et ne sera visible que dans l'assembly de la classe,
- l'autre, public, mais qui sera exclu de la sérialisation.

Dans les objets de notre assembly, nous allons utiliser l'évènement marqué Internal, et pour l'interface graphique, nous n'auront pas d'autre choix que d'utiliser l'autre évènement.

Cette méthode de programmation implique deux choses :
- Déclarer deux évènements distincts et les lancer quand besoin est,
- A la désérialisation, les évènements internes seront restaurés !

Source / Exemple :


[Serializable]
	public class Operation{

		// La valeur de notre opération bancaire
		private Single m_Value;

		// L'évènement utilisé par l'interface graphique, et qui sera exclu de la sérialisation
		[field: NonSerialized]
		public event EventHandler onValueChanged;

		// L'évènement utilisé par les autres classes de l'API, et qui ne sera pas exclu de la sérialisation
		internal event EventHandler onValueChangedInternal;

		// L'éccesseur
		public Single Value {
			set {
				// On vérifie que la valeur est différente de ce que l'on a déjà, et si ce n'est pas le cas, on lance les deux évènement.
				if(m_Value != value) {
                    			if (onValueChangedInternal != null)
                        			onValueChangedInternal(this, EventArgs.Empty);
					if(onValueChanged != null)
						onValueChanged(this, EventArgs.Empty);
				}
			}
			get { return m_Value; }
		}
	}

Conclusion :


Ce code n'a pas pour but d'être réutilisé "tel-quel", mais il a plus pour vocation de vous aider dans la création de vos API. Il s'agit donc plutot ici de "design rules".

A voir également

Ajouter un commentaire

Commentaires

bkso
Messages postés
1
Date d'inscription
samedi 16 juin 2007
Statut
Membre
Dernière intervention
30 septembre 2008

Moi aussi j'ai eu un probleme de ce genre, mais vus qu' à l'epoque je n'en connaissais rien aux evenements j'ai du change totalemen de strategie.
merci pour cette astuce.
cs_yoannd
Messages postés
305
Date d'inscription
lundi 7 janvier 2002
Statut
Membre
Dernière intervention
10 août 2011
4
J'ai amélioré un peu le concept. Vous pouvez retrouver un nouveau tutoriel sur ce sujet ici :
http://www.csharpfr.com/tutoriaux/PROPRIETES-ACCESSEURS-EVENEMENTS-CLASSE-EVENEMENTS-SERIALISATION_816.aspx
cs_yoannd
Messages postés
305
Date d'inscription
lundi 7 janvier 2002
Statut
Membre
Dernière intervention
10 août 2011
4
Vraiment ?

Sans mentir, je connaissais le coup du [field: NonSerialized], mais je n'avais pas vu cette astuce ailleurs (promis).

Au moins, je suis pas le seul à avoir pensé un truc pareil : ça fait plaisir :)
cs_coq
Messages postés
6352
Date d'inscription
samedi 1 juin 2002
Statut
Modérateur
Dernière intervention
2 août 2014
79
Moui l'event est en quelque sorte un champs comme un autre.
Je me souviens d'avoir lue cette astuce avec quelques explications supplémentaires il y a quelques temps mais je ne sais plus où.
cs_yoannd
Messages postés
305
Date d'inscription
lundi 7 janvier 2002
Statut
Membre
Dernière intervention
10 août 2011
4
Ha oui, au fait : les évènements sont bien sérialisés...

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.