// ========================================================================
//
// 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;

namespace ex_015_001_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";
    }

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

            Etudiant[] tableauEtudiants = new Etudiant[10];
            for (int i = 0; i < tableauEtudiants.Length; i++)
            {
                tableauEtudiants[i] = new Etudiant();
            }

            WriteLine("Méthode avec random non static");
            for (int i = 0; i < tableauEtudiants.Length; i++)
            {
                WriteLine($"L'étudiant {i} a obtenu la note de {tableauEtudiants[i].GenereNoteAvecRandomNonStatic()}/20");
            }
            WriteLine();

            WriteLine("Méthode avec random static");
            for (int i = 0; i < tableauEtudiants.Length; i++)
            {
                WriteLine($"L'étudiant {i} a obtenu la note de {tableauEtudiants[i].GenereNoteAvecRandomStatic()}/20");
            }
            WriteLine();

            WriteLine("Année");
            //pour appeler les membres non statiques et les méthodes non statiques,
            //une instance est obligatoire
            Etudiant étudiant = new Etudiant();
            WriteLine(étudiant.Année);
            WriteLine(étudiant.GetAnnéeFormation());
            WriteLine();

            WriteLine("Formation");
            //pour appeler les membres statiques et les méthodes statiques,
            //on utiliser les méthodes sur le type lui-même, sans instances
            WriteLine(Etudiant.Formation);
            WriteLine(Etudiant.GetFormation());
            WriteLine();

            WriteLine("Autre exemple de propriété statique : DateTime.Now");
            WriteLine($"DateTime.Now = {DateTime.Now}");
        }
    }
}
