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

using System.Collections.Generic;

namespace ex_023_016_ReadOnlyCollection
{
    class Program
    {
        /// <summary>
        /// L'exemple suivant montre comment encapsuler une collection d'un type dans les deux cas principaux suivants :
        /// 1) le type est immuable (en façade au moins), c'est-à-dire qu'on ne peut pas modifier son état interne en appelant ses méthodes ou propriétés
        ///     => MonLit possède une collection privée mNounours de Nounours où Nounours est immuable
        /// 2) le type est mutable, ie que l'utilisateur peut modifier l'état interne de ses instances, et notre API l'autorise.
        ///     => MonLit2 possède une collection privée mNounours2 de Nounours2 où Nounours2 est mutable
        /// Comment encapsuler correctement une collection d'un tel type ?
        /// Dans l'exemple suivant, nous voulons protéger la collection contre :
        /// - les modifications de la collection (ajout ou suppression d'éléments),
        /// - la modification de la collection elle-même (on ne doit pas pouvoir faire de new)
        /// Nous ne cherchons pas à protéger les éléments de la collection (en particulier si le type n'est pas immuable).
        /// En résumé, nous cherchons à rendre publique en lecture seule, la collection privée de nounours du lit.
        /// </summary>
        static void Main(string[] args)
        {
            //Test avec MonLit qui possède une collection d'un type immuable (Nounours)
            MonLit monlit = new MonLit();

            monlit.NounoursList.RemoveAt(0); // dangereux !

            (monlit.NounoursIEnumerable as List<Nounours>).RemoveAt(0); // c'est mieux, mais pas suffisant... 

            (monlit.NounoursIROC as List<Nounours>).RemoveAt(0); // idem

            //List<Nounours> test = (monlit.NounoursROC as List<Nounours>); // pas possible
            //monlit.NounoursROC[0] = new Nounours(5, "betterave", DateTime.Now, 0); // pas possible

            //List<Nounours> test = (monlit.NounoursROC2 as List<Nounours>); // pas possible
            //monlit.NounoursROC2[0] = new Nounours(5, "betterave", DateTime.Now, 0); // pas possible





            //Test avec MonLit2 qui possède une collection d'un type mutable (Nounours2)
            MonLit2 monlit2 = new MonLit2();

            monlit2.Nounours2List.RemoveAt(0); // dangereux !

            (monlit2.Nounours2IEnumerable as List<Nounours2>).RemoveAt(0); // c'est mieux, mais pas suffisant... 

            (monlit2.Nounours2IROC as List<Nounours2>).RemoveAt(0); // idem

            //List<Nounours> test = (monlit2.Nounours2ROC as List<Nounours2>); // pas possible
            //monlit2.Nounours2ROC[0] = new Nounours2(5, "betterave", DateTime.Now, 0); // pas possible

            //List<Nounours> test = (monlit2.Nounours2ROC2 as List<Nounours2>); // pas possible
            //monlit2.Nounours2ROC2[0] = new Nounours2(5, "betterave", DateTime.Now, 0); // pas possible

            //on peut toujours modifier les instances de Nounours2, mais c'était voulu !
            monlit2.Nounours2ROC[0].NbPoils = 1;

        }
    }
}
