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

using System;
using static System.Console;
using static ex_015_004_using_static.Etudiant;
using static ex_015_004_using_static.BacOrigine;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ex_015_004_using_static
{
    public class Etudiant
    {
        Random random = new Random();

        public int GenereNoteAvecRandomNonStatic()
        {
            return random.Next(0, 21);
        }

        static Random randomStatic;

        public int GenereNoteAvecRandomStatic()
        {
            return randomStatic.Next(0, 21);
        }

        //un constructeur static est nécessairement privé et ne peut pas être appelé directement
        //il sera appelé lors de la première construction d'un objet de ce type
        static Etudiant()
        {
            randomStatic = new Random();
            //ici, il est évidemment préférable d'utiliser l'initialiseur plutôt que le constructeur pour Random
            //mais c'est juste pour l'exemple d'un constructeur static
        }

        //membre non statique
        public string Année = "2013-2014";

        //méthode non statique
        public string GetAnnéeFormation()
        {
            //une méthode non statique peut utiliser aussi bien des membres non statiques que des membres statiques
            return $"{Formation} ({Année})";
        }

        //membre statique (partagé par toutes les instances de cette classe)
        public static string Formation = "DUT Informatique";

        //méthode statique
        public static string GetFormation()
        {
            //une méthode statique ne peut pas utiliser de membres non statiques 
            //return string.Format("{0} ({1})", Formation, Année);

            //une méthode statique ne peut utiliser que des membres statiques
            return $"{Formation} ({Université})";
        }

        //un membre const est toujours statique, même si on ne le précise pas dans la syntaxe
        public const string Université = "Université d'Auvergne";

        public BacOrigine Origine;
    }

    public enum BacOrigine
    {
        Inconnu,
        S,
        ES,
        L,
        STI2D
    }

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

            WriteLine("sans : using static ex_015_004_using_static.Etudiant;    il faudrait écrire :");
            WriteLine($"Etudiant.Formation : {Etudiant.Formation}");
            WriteLine($"Etudiant.Université : {Etudiant.Université}");
            WriteLine($"Etudiant.GetFormation() : {Etudiant.GetFormation()}");
            WriteLine();
            WriteLine("grâce à : using static ex_015_004_using_static.Etudiant;    on peut simplement écrire :");
            WriteLine($"Formation : {Formation}");
            WriteLine($"Université : {Université}");
            WriteLine($"GetFormation() : {GetFormation()}");
            WriteLine();
            WriteLine("C'est d'ailleurs la même chose pour l'utilisation de la Console :");
            WriteLine("sans :  using static System.Console;     il faudrait écrire :");
            string prout = "prout";
            WriteLine($"Console.WriteLine(\"prout\");");
            Console.WriteLine(prout);
            WriteLine();
            WriteLine("grâce à : using static System.Console;    on peut écrire :");
            WriteLine($"WriteLine(\"prout\");");
            WriteLine(prout);
            WriteLine();
            WriteLine("Marche également avec les enum");
            WriteLine("sans : using static ex_015_004_using_static.BacOrigine;     il faudrait écrire");
            WriteLine("e.Origine = BacOrigine.STI2D;");
            Etudiant e = new Etudiant();
            e.Origine = BacOrigine.STI2D;
            WriteLine();
            WriteLine("grâce à : using static ex_015_004_using_static.BacOrigine;     on peut écrire");
            WriteLine("e.Origine = STI2D;");
            e.Origine = STI2D;
            WriteLine();
            WriteLine("Tout cela marche très bien, tant que le compilateur ne détecte aucune ambiguité");

        }
    }
}
