diff --git a/ex_038_006_Binary_Serializable/Nounours.cs b/ex_038_006_Binary_Serializable/Nounours.cs new file mode 100644 index 0000000..803bc5d --- /dev/null +++ b/ex_038_006_Binary_Serializable/Nounours.cs @@ -0,0 +1,133 @@ +// ======================================================================== +// +// Copyright (C) 2016-2017 MARC CHEVALDONNE +// marc.chevaldonne.free.fr +// +// Module : Nounours.cs +// Author : Marc Chevaldonné +// Creation date : 2016-10-07 +// +// ======================================================================== + +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.Serialization; + +namespace ex_038_006_Binary_Serializable +{ + /// + /// Pour que Nounours soit sérialisable/désérialisable avec un Binary Serializer, il faut décorer le type avec l'attribut [Serializable] + /// 1) pour cela, il faut ajouter [Serializable] à la définition du type comme ci-dessous. + /// 2) contrairement au DataContract Serializer, on ne rajoute pas d'attributs pour chaque membre à sérialiser. On n'en rajoute que pour ne pas sérialiser. + /// L'attribut à ajouter dans ce cas est [NonSerialized]. Tous les autres membres publics ou privés sont sérialisés. + /// + /// Attention en conséquence aux propriétés automatiques : puisqu'un membre est créé par le compilateur, celui-ci est sérialisé, mais son nom peut changer à compilation. + /// Il faut donc éviter les propriétés automatiques qui doivent être sérialisées. + /// + /// Il faut également faire attention aux membres de types collection (et en particulier aux types abstraits qui sont désérialisés en Array) comme pour les DataContractSerializers. + /// + /// Enfin, comme pour le DataContractSerializer, on trouve les 4 hooks : [OnDeserializing], [OnDeserialized], [OnSerializing] et [OnSerialized] + /// (enlevez l'attribut [OnDeserializing] devant la méthode Init pour constater les dégâts) + /// + [Serializable] + public class Nounours + { + public string Nom + { + get { return nom; } + set { nom = value; } + } + private string nom; + + public DateTime Naissance + { + get { return naissance; } + set { naissance = value; } + } + private DateTime naissance; + + public int NbPoils + { + get; + set; + } + + [NonSerialized] + private int entierQuiSertARienMaisQuOnNeVeutPasSerialiser = 42; + + public List Amis + { + get; + set; + } + + public Nounours() + { + Init(); + Amis = new List(); + } + + [OnDeserializing] + void Init(StreamingContext sc = new StreamingContext()) + { + entierQuiSertARienMaisQuOnNeVeutPasSerialiser = 42; + } + + /// + /// returns a hash code in order to use this class in hash table + /// + /// hash code + public override int GetHashCode() + { + return Nom.GetHashCode(); + } + + /// + /// checks if the "right" object is equal to this Nounours or not + /// + /// the other object to be compared with this Nounours + /// true if equals, false if not + public override bool Equals(object right) + { + //check null + if (object.ReferenceEquals(right, null)) + { + return false; + } + + if (object.ReferenceEquals(this, right)) + { + return true; + } + + if (this.GetType() != right.GetType()) + { + return false; + } + + return this.Equals(right as Nounours); + } + + /// + /// checks if this Nounours is equal to the other Nounours + /// + /// the other Nounours to be compared with + /// true if equals + public bool Equals(Nounours other) + { + return (this.Nom.Equals(other.Nom) && this.Naissance == other.Naissance); + } + + public override string ToString() + { + string amisStr = String.Empty; + if(Amis.Count > 0) + { + amisStr = $", amis : {Amis.Select(nounours => nounours.Nom).Aggregate((noms, n) => $"{noms} {n}")}"; + } + return $"{Nom} ({Naissance:dd/MM/yyyy}, {NbPoils} poils{amisStr}, 42? {entierQuiSertARienMaisQuOnNeVeutPasSerialiser})"; + } + + } +} diff --git a/ex_038_006_Binary_Serializable/Program.cs b/ex_038_006_Binary_Serializable/Program.cs index 1a08f5b..f7a9459 100644 --- a/ex_038_006_Binary_Serializable/Program.cs +++ b/ex_038_006_Binary_Serializable/Program.cs @@ -5,21 +5,79 @@ // // Module : Program.cs // Author : Marc Chevaldonné -// Creation date : 2016-10-12 +// Creation date : 2016-10-07 // // ======================================================================== +using System; +using System.IO; +using System.Runtime.Serialization; +using System.Runtime.Serialization.Formatters.Binary; +using static System.Console; namespace ex_038_006_Binary_Serializable { /// - /// Pas d'équivalent en .NET Core car trop lié à Windows - /// Dirigez-vous vers un DataContractSerializer + /// /// - public class Program + class Program { - public static void Main(string[] args) + static void Main(string[] args) { + Directory.SetCurrentDirectory(Path.Combine(Directory.GetCurrentDirectory(), "..//..//..//..//ex_038_006_Binary_Serializable", "result")); + + Nounours chewie = new Nounours() + { + Nom = "Chewbacca", + Naissance = new DateTime(1977, 5, 27), + NbPoils = 1234567 + }; + + Nounours yoda = new Nounours() + { + Nom = "Yoda", + Naissance = new DateTime(1980, 5, 21), + NbPoils = 3 + }; + + Nounours ewok = new Nounours() + { + Nom = "Ewok", + Naissance = new DateTime(1983, 5, 25), + NbPoils = 3456789 + }; + + chewie.Amis.Add(yoda); + chewie.Amis.Add(ewok); + + WriteLine(chewie); + + + //ATTENTION : pour que le Binary Serializer fonctionne, vous devez avoir décoré l'objet à sérialiser ! + //cf. Nounours.cs + + + //1. Sérialisation d'un chewie en binaire avec la méthode par défaut + //On construit le sérialiseur binaire en précisant le formatter (BinaryFormatter ou SoapFormatter) + //- le formatter binaire est le plus efficace des deux et permet d'obtenir la sortie la plus légère + //- le formatter Soap permet d'obtenir un formatage dans le style du protocole SOAP. + // Attention, il ne prend pas en charge la sérialisation des types génériques comme List ! + string file = "nounours.bin"; + IFormatter formatter = new BinaryFormatter(); + using (FileStream stream = File.Create(file)) + { + formatter.Serialize(stream, chewie); + } + + //- pour désérialiser, on crée le flux (de préférence avec using) en lecture + //- on appelle Deserialize + Nounours nounours2; + using (FileStream stream = File.OpenRead(file)) + { + nounours2 = formatter.Deserialize(stream) as Nounours; + } + + WriteLine(nounours2); } } } diff --git a/ex_038_006_Binary_Serializable/ex_038_006_Binary_Serializable.csproj b/ex_038_006_Binary_Serializable/ex_038_006_Binary_Serializable.csproj new file mode 100644 index 0000000..21dff5c --- /dev/null +++ b/ex_038_006_Binary_Serializable/ex_038_006_Binary_Serializable.csproj @@ -0,0 +1,8 @@ + + + + Exe + netcoreapp2.2 + + + diff --git a/ex_038_006_Binary_Serializable/result/.gitignore b/ex_038_006_Binary_Serializable/result/.gitignore new file mode 100644 index 0000000..6495aa5 --- /dev/null +++ b/ex_038_006_Binary_Serializable/result/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory + +# Except this file +!.gitignore \ No newline at end of file