Partage
  • Partager sur Facebook
  • Partager sur Twitter

[C#] ~ Liste, Tableau... Enumerable

    7 juillet 2019 à 15:49:23

    Bonjour à tous,

    J'ai récemment repris le C# suite à une petite année de Python. Une idée m'est venue de recréer une fonctionnalité de Python et de la retranscrire en C#.

    Le but était dans un premier temps de créer une fonction qui reçoit un tableau  de n'importe quel type et de l'afficher. J'ai réussi à la créer avec une conversion d'Object en Array puis d'une boucle foreach (var value in (Array)o).

    J'ai voulu étendre cette méthode pour les listes également (et si possible pour tous les objets "conteneurs").

    Après création de différents type de tableaux (à une ou plusieurs dimensions) et de listes, je suis étonné de certain résultat.

    Des tableaux de string sont des IEnumerable, ainsi que des listes de string, mais des tableaux de int ou de bool ne le sont pas mais sont des Array,  et enfin des listes de int ou de bool ne sont ni IEnumerable ni Array. Pourtant ce sont des listes...

    Pouvez vous m'éclairer car je ne vois pas comment une liste n'est pas un IEnumerable, ou encore pourquoi des str[] le sont, mais des int[] ne le sont pas.

    PS: Je n'ai pas fait le cours sur les interfaces, j'ai juste eu des explications à l'oral.

    Voici mon code si vous voulez le tester pour mieux comprendre et voir les résultats :

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace printEnum
    {
        class Humain
        {
            public string nom { get; set; }
            public Humain(string _name)
            {
                nom = _name;
            }
    
            public override string ToString()
            {
                return nom;
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                // Array[]
                string[] tabStr = new string[] { "Saleté", "de", "cafards", "de", "merde." };
                int[] tabInt = new int[] { 1, 2, 3, 4, 5 };
                bool[] tabBool = new bool[] { true, false, false, true };
                Humain[] tabHumain = new Humain[] { new Humain("Gab"), new Humain("Joe"), new Humain("Cesar") };
    
                // << tableaux multidimensionnels >>
                int[,] tab_2_dim_int = new int[2, 5] { { 1, 2, 3, 4, 5 }, { 1, 2, 3, 4, 5 }}; 
                    // tableau 'int' a 2 dimensions avec 2 tableaux 'int' a 5 places
                string[,] tab_2_dim_str = { {"1_1", "1_2" }, { "2_1", "2_2" } , { "3_1", "3_2" } , { "4_1", "4_2" } }; 
                    // tableau 'str' a 2 dimensions avec 2 tableaux 'str' a 5 places
                int[,,] tab_3_dim_int = new int[2, 3, 4] {
                    { { 111, 112, 113, 114}, { 121, 122, 123, 124}, { 131, 132, 133, 134} },
                    { { 211, 212, 213, 214}, { 221, 222, 223, 224}, { 231, 232, 233, 234} } };
                    // tableau 'int' a 3 dimensions avec 2 tableaux 'int' de 3 tableaux a 4 places
    
                // << tableau escalier ou tableau de tableau >>
                int[][] tabStepInt = new int[5][];
                tabStepInt[0] = tabInt;
                tabStepInt[1] = new int[] { 11, 12, 13, 14, 15, 16 };
                tabStepInt[2] = new int[] { 21, 22, 23, 24, 25, 26, 27 };
                tabStepInt[3] = new int[] { 31, 32, 33, 34, 35, 36, 37, 38 };
                tabStepInt[4] = new int[] { 41, 42, 43, 44, 45, 46, 47, 48, 49 };
    
    
                // List<>
                List<string> listStr = new List<string> { "Saleté", "de", "cafards", "de", "merde." };
                List<int> listInt = new List<int> { 1, 10, 2, 15, 3 };
                List<bool> listBool = new List<bool> { true, false, false, true };
                List<Humain> listHumain = new List<Humain> { new Humain("Gab"), new Humain("Joe"), new Humain("Cesar") };
    
                List<List<string>> ListStepStr = new List<List<string>> { new List<string> { "t_1", "t_2" }, new List<string> { "t_11", "t_12" } };
                List<List<int>> ListStepInt_1 = new List<List<int>> { new List<int> { 1, 2 }, new List<int> { 11, 12 } };
                List<int[]> ListStepInt_2 = new List<int[]> { new int[]{ 1, 2 }, new int[] { 11, 22, 33 }, new int[] { 111, 222, 333, 444 } };
    
    
                // << test >>
                AffichageTitre("Affichage des tableaux simples");
                AffichageTitre("Tab Str", false);
                PrintEnumerable(tabStr);
                AffichageTitre("Tab Int", false);
                PrintEnumerable(tabInt);
                AffichageTitre("Tab Bool", false);
                PrintEnumerable(tabBool);
                AffichageTitre("Tab Humain", false);
                PrintEnumerable(tabHumain);
                AffichageTitre("Affichage des tableaux multidimensionnels");
                AffichageTitre("Tab Dim 2 Int", false);
                PrintEnumerable(tab_2_dim_int);
                AffichageTitre("Tab Dim 3 Int", false);
                PrintEnumerable(tab_3_dim_int);
                AffichageTitre("Tab Dim 2 Str", false);
                PrintEnumerable(tab_2_dim_str);
                AffichageTitre("Affichage des tableaux escaliers");
                AffichageTitre("Tab Tab Int", false);
                PrintEnumerable(tabStepInt);
    
                AffichageTitre("Affichage des listes simples");
                AffichageTitre("List Str", false);
                PrintEnumerable(listStr);
                AffichageTitre("List Int", false);
                PrintEnumerable(listInt);
                AffichageTitre("List Bool", false);
                PrintEnumerable(listBool);
                AffichageTitre("List Humain", false);
                PrintEnumerable(listHumain);
                AffichageTitre("Affichage des listes escaliers");
                AffichageTitre("List List Str", false);
                PrintEnumerable(ListStepStr);
                AffichageTitre("List List Int", false);
                PrintEnumerable(ListStepInt_1);
                AffichageTitre("List Tab Int", false);
                PrintEnumerable(ListStepInt_2);
            }
    
    
            static void AffichageTitre(string titre, bool estTitre = true)
            {
                if (estTitre)
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("\n " + titre + "\n");
                    Console.ForegroundColor = ConsoleColor.White;
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Cyan;
                    Console.WriteLine(titre);
                    Console.ForegroundColor = ConsoleColor.White;
                }
            }
    
            static void PrintEnumerable(object o)
            {
                if (o is IEnumerable<object>)
                {
                    foreach (var value in (IEnumerable<object>)o)
                    {
                        if (value is IEnumerable<object> || value is Array)
                        {
                            PrintEnumerable(value);
                        }
                        else
                        {
                            Console.WriteLine("List : " + value);
                        }
                    }
                }
                else if (o is Array)
                {
                    foreach (var value in (Array)o)
                    {
                        if (value is Array || value is IEnumerable<object>)
                        {
                            PrintEnumerable(value);
                        }
                        else
                        {
                            Console.WriteLine("Tab : " + value);
                        }
                    }
                }
                else 
                {
                    Console.WriteLine("Object is not a enumerable : " + o);
                }
                Console.ReadKey(true);
            }
        }
    }
    



    -
    Edité par Roman Clavier 7 juillet 2019 à 15:53:08

    • Partager sur Facebook
    • Partager sur Twitter

    roman-cubz-and-progz.000webhostapp.com

      9 juillet 2019 à 8:56:58

      Pour savoir quelles interfaces sont implémentées par tel ou tel type tu peux juste faire :

      // remplacer int [] par le type souhaité
      foreach (var interfaceType in typeof (int []).GetInterfaces ())
          Console.WriteLine (interfaceType.Name);
      

      Et tu obtiendras quelque chose de ce genre :

      ICloneable
      IList
      ICollection
      IEnumerable
      IStructuralComparable
      IStructuralEquatable
      IList`1
      ICollection`1
      IEnumerable`1
      IReadOnlyList`1
      IReadOnlyCollection`1

      les `1 ou `2 que tu peux obtenir sont juste la représentation d'un type générique donc comprendre que ITruc`1 signifie ITruc<T> et IMachin`2 signifie IMachin<T1, T2>

      De là on peut constater que les tableaux implémentent bien IEnumerable<T> (ou sa version non générique IEnumerable dans le cas de tableaux multi-dimensionnels exemple int [,])

      Ton souci vient de la covariance et de la contravariance, j'ai plus les détails exact en tête donc je préfère éviter d'écrire trop d'âneries là mais globalement ton souci vient du fait que tu testes avec IEnumerable<object> (probablement une histoire de types valeurs/références et de boxing entre int ou bool et object)


      • Partager sur Facebook
      • Partager sur Twitter
      Censément, quelqu'un de sensé est censé s'exprimer sensément.

      [C#] ~ Liste, Tableau... Enumerable

      × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
      × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
      • Editeur
      • Markdown