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

using Namespace2;
using System;
using static System.Console;

namespace ex_028_014_Func
{
    /// <summary>
    /// .NET contient déjà un certain nombre de types délégués dans l'espace de noms System.
    /// Parmi eux, on peut distinguer notamment la famille des Predicate, des Func et des Action.
    /// Cet exemple présente le délégué Func.
    /// 
    /// Le délégué Func est multi-générique et a la forme suivante :
    /// delegate TResult Func<T1, T2, TResult>(T1 arg1, T2 arg2);
    /// Mais il y en a de nombreux dans le framework :
    /// Func<TResult>
    /// Func<T1, TResult>
    /// Func<T1, T2, TResult>
    /// Func<T1, T2, T3, TResult>
    /// Func<T1, T2, T3, T4, TResult>
    /// Func<T1, T2, T3, T4, T5, TResult>
    /// Func<T1, T2, T3, T4, T5, ..., T16, TResult>
    /// 
    /// N'importe quelle instance d'un Func<T1, ..., Ti, TResult> est donc une méthode prenant en paramètres 
    /// un T1, un T2, un T3, ... un Ti et rendant un TResult.
    /// 
    /// Ils permettent de coder très rapidement une Strategy par exemple.
    /// L'exemple suivant reprend le 028_007 en utilisant le délégué Func<int, int>
    /// </summary>
    class Program
    {
        Func<int, int> MonModifieur;

        public void Modifie(int[] tab)
        {
            for (int i = 0; i < tab.Length; i++)
            {
                tab[i] = MonModifieur(tab[i]);
            }
        }

        public Program(Func<int, int> modifieur)
        {
            MonModifieur = modifieur;
        }

        static void Main(string[] args)
        {
            int[] tableau = { 1, 2, 3, 4, 5 };
            Program p = new Program(MaClasseDeMaths.Carré);
            p.Modifie(tableau);
            foreach (int i in tableau)
            {
                Write($"{i} ");
            }
            WriteLine();

            p = new Program(MaClasseDeMaths.Cube);
            p.Modifie(tableau);
            foreach (int i in tableau)
            {
                Write($"{i} ");
            }
            WriteLine();

            p = new Program(new Droite(2, 3).Image);
            p.Modifie(tableau);
            foreach (int i in tableau)
            {
                Write($"{i} ");
            }
            WriteLine();
        }
    }
}
