// ========================================================================
//
// Copyright (C) 2016-2017 MARC CHEVALDONNE
//                         marc.chevaldonne.free.fr
//
// Module        : Program.cs
// Author        : Marc Chevaldonné
// Creation date : 2016-01-10
//
// ========================================================================

using static System.Console;

namespace ex_023_018_ReadOnlyDictionaries
{
    class Program
    {
        /// <summary>
        /// L'exemple suivant montre comment encapsuler un dictionnaire dans les cas suivants :
        /// => les clés et/ou valeurs sont mutables, c'est-à-dire qu'on peut modifier leur état interne en appelant leurs méthodes ou propriétés
        ///     => MonLit possède un dictionnaire de paire clé (string)- valeur (Nounours) privée mNounoursDico où Nounours est mutable
        /// Comment encapsuler correctement un dictionnaire de ce type ?
        /// Dans l'exemple suivant, nous voulons protéger le dictionnaire contre :
        /// - les modifications du dictionnaire (ajout ou suppression d'éléments),
        /// - la modification du dictionnaire lui-même (on ne doit pas pouvoir faire de new)
        /// 
        /// En résumé, nous cherchons à rendre publique en lecture seule, le dictionnaire privé, en laissant chacun de ses éléments modifiables.
        /// 
        /// La bonne solution consiste à :
        /// - envelopper (wrapper) le dictionnaire privé avec un ReadOnlyDictionary construit dans le constructeur de MonLit.
        /// - tant qu'en interne, dans la classe MonLit, on ne change pas la référence de mNounoursDico, le wrapper donne accès en lecture seule au dictionnaire
        /// - attention de bien penser à le reconstruire si la référence change !!!
        static void Main(string[] args)
        {
            MonLit monlit = new MonLit();

            //lecture d'un nounours existant dans le dictionnaire :
            var singe = monlit.Nounours["Singe"];
            WriteLine($"{singe.Nom} ({singe.DateDeNaissance.ToString("d")}, nbpoils : {singe.NbPoils})");

            //tentative d'ajout d'un nouveau nounours : impossible, dictionnaire en lecture seule
            //monlit.Nounours["Truite"] = new Nounours(3, "Truite", new System.DateTime(2013, 9, 3), 0);

            //les éléments ne sont pas immuables, mais c'est voulu, on peut donc les modifier
            singe.NbPoils += 1000;
            WriteLine($"{singe.Nom} ({singe.DateDeNaissance.ToString("d")}, nbpoils : {singe.NbPoils})");
        }
    }
}
