Je me suis apercu que la serialisation de liste générique avec un SoapFormater n'était pas pris en charge.
J'ai donc cherché a détourné le problème.
public class AxSerialiser<T> { public static void SoapSerialiseToFile(string _Path, T _Object) { try { FileStream _FileStream = new FileStream(_Path, FileMode.OpenOrCreate, FileAccess.Write); SoapFormatter soapFormatter = new SoapFormatter(); soapFormatter.Serialize(_FileStream, _Object); _FileStream.Close(); } catch (Exception e) { MessageBox.Show("Failed SoapSerialiseToFile.rnReason : " + e.Message, "WARNING", MessageBoxButtons.OK, MessageBoxIcon.Warning); } } }
Ceci utilisé avec un objet contenant une Liste<T> renvoie une erreur.
J'ai donc implémenté la classe suivante.
/// <summary> /// Classe générique fournissant une System.Collections.Generic.List /// et l'implementation de ISerializable permettant de la sérialiser a l'aide d'un SoapFormatter. /// </summary> /// <typeparam name="T">The type of elements in the list.</typeparam> [Serializable] public abstract class GenericListClassObject<T> : ISerializable { /// <summary> /// La Liste fournie par notre classe /// </summary> List<T> _List = new List<T>(); /// <summary> /// La propriété marquée comme "virtual". /// c'est pratique pour voir de quoi on parle dans la classe dérivée. /// </summary> public virtual List<T> List { get { return _List; } set { _List = value; } } /// <summary> /// Le constructeur /// </summary> public GenericListClassObject() { } #region Membres de ISerializable /// <summary> /// Le "déconstructeur" utilisé pour la sérialisation. /// </summary> /// <param name="info">Stores all the data needed to serialize or deserialize an object.</param> /// <param name="context">Describes the source and destination of a given serialized stream, and provides an additional caller-defined context.</param> public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { ///On vas tout simplement transformer notre Liste de 'T' en un tableau de 'T' ///et l'ajouter au SerializationInfo. info.AddValue("_List", _List.ToArray(), typeof(T[])); Type t = this.GetType(); info.AddValue("TypeObj", t); } /// <summary> /// Le constructeur Utilisé pour la désérialisation /// </summary> /// <param name="si">Stores all the data needed to serialize or deserialize an object.</param> /// <param name="context">Describes the source and destination of a given serialized stream, and provides an additional caller-defined context.</param> public GenericListClassObject(SerializationInfo si, StreamingContext context) { ///On récupere notre tableau d'objets 'T' dans SerializationInfo. T[] tmp = (T[])si.GetValue("_List", typeof(T[])); ///On remet les elements du tableau dans notre Liste. _List = new List<T>((IEnumerable<T>) tmp); } #endregion }
On peut donc utiliser une classe telle que celle ci:
/// </summary> [Serializable] public class Hotel : GenericListClassObject<Chambre>,ISerializable { /// <summary> /// Champ 'nom', le nom de notre hotel /// </summary> string nom = "Hotel Bel air"; /// <summary> /// Propriéte 'Nom'. /// </summary> public string Nom { get { return nom; } set { nom = value; } } /// <summary> /// Propriéte List, celle ci est fournie par notre classe 'GenericListClassObject'. /// </summary> public override List<Chambre> List { get {return base.List;} set {base.List = value;} } /// <summary> /// Le constructeur Utilisé pour la désérialisation /// </summary> /// <param name="si">Stores all the data needed to serialize or deserialize an object.</param> /// <param name="context">Describes the source and destination of a given serialized stream, and provides an additional caller-defined context.</param> public Hotel(SerializationInfo si, StreamingContext context) { } /// <summary> /// Le constructeur. /// </summary> public Hotel() { } }
Le tour est joué.