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

using static System.Console;

//cet exemple montre trois manières différentes de gérer les paramètres par défaut
namespace ex_010_003_interets_des_optionalparameters
{
    class C1
    {
        /// <summary>
        /// une méthode qui gère les paramètres remplis avec null : 
        /// l'utilisateur doit toujours renseigner chaque paramètre
        /// </summary>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        /// <param name="s3"></param>
        /// <returns></returns>
        public static string Method(string s1, string s2, string s3)
        {
            if (s1 == null)
            {
                s1 = "nothing";
            }
            if (s2 == null)
            {
                s2 = "nothing";
            }
            if (s3 == null)
            {
                s3 = "nothing";
            }
            return string.Format($"{s1} + {s2} + {s3}");
        }
    }

    class C2
    {
        /// <summary>
        /// la méthode Method possède trois overload afin de gérer des valeurs par défaut
        /// Risque de confusion et impossibilité de faire toutes les combinaisons.
        /// </summary>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        /// <param name="s3"></param>
        /// <returns></returns>
        public static string Method(string s1, string s2, string s3)
        {
            return string.Format($"{s1} + {s2} + {s3}");
        }
        public static string Method(string s1, string s2)
        {
            return string.Format($"{s1} + {s2} + nothing");
        }
        public static string Method(string s)
        {
            return string.Format($"{s} + nothing + nothing");
        }
    }

    class C3
    {
        /// <summary>
        /// avec les paramètres optionnels, toutes les combinaisons sont possibles et une seule méthode suffit.
        /// Un seul inconvénient : les noms des paramètres font maintenant partis de l'API
        /// </summary>
        /// <param name="s1"></param>
        /// <param name="s2"></param>
        /// <param name="s3"></param>
        /// <returns></returns>
        public static string Method(string s1 = "nothing", string s2 = "nothing", string s3 = "nothing")
        {
            return string.Format($"{s1} + {s2} + {s3}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            OutputEncoding = System.Text.Encoding.UTF8;

            WriteLine("Méthode 1 : tous les champs doivent toujours être renseignés");
            WriteLine("C1.Method(\"a\", \"b\", \"c\")");
            WriteLine(C1.Method("a", "b", "c"));
            WriteLine("C1.Method(\"a\", \"b\", null)");
            WriteLine(C1.Method("a", "b", null));
            WriteLine("C1.Method(\"a\", null, null)");
            WriteLine(C1.Method("a", null, null));
            WriteLine("C1.Method(null, \"b\", null)");
            WriteLine(C1.Method(null, "b", null));

            WriteLine();
            WriteLine("Méthode 2 : Overloads");
            WriteLine("C2.Method(\"a\", \"b\", \"c\")");
            WriteLine(C2.Method("a", "b", "c"));
            WriteLine("C2.Method(\"a\", \"b\")");
            WriteLine(C2.Method("a", "b"));
            WriteLine("C2.Method(\"a\")");
            WriteLine(C2.Method("a"));

            WriteLine();
            WriteLine("Méthode 3 : optional parameters and named parameters");
            WriteLine("C3.Method(\"a\", \"b\", \"c\")");
            WriteLine(C3.Method("a", "b", "c"));
            WriteLine("C3.Method(\"a\", \"b\")");
            WriteLine(C3.Method("a", "b"));
            WriteLine("C3.Method(\"a\")");
            WriteLine(C3.Method("a"));
            WriteLine("C3.Method(s2:\"b\")");
            WriteLine(C3.Method(s2: "b"));
        }
    }
}
