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

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

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.