vendredi 14 août 2009

L’instruction yield pour récupérer la sélection d’éléments d’une liste

L'idée n'est pas de faire un cours sur l'instruction yield, pour cela voir les liens suivants :

http://msdn.microsoft.com/fr-fr/library/9k7k7cf0.aspx

http://romainverdier.developpez.com/articles/dotnet/le-mot-cle-yield-et-les-iterateurs-en-csharp/

Mais de donner un petit plus quand on code avec des listes et très souvent on refait la même chose à savoir récupérer la sélection d'une liste pour lui appliquer un traitement particulier.

Donc le but du jeu est ; Comment peut-on faire pour éviter la duplication des Foreach ou While ou autre afin de récupérer une sélection d’éléments ?
Pour être le plus souple possible, je propose d’utiliser une méthode, nommé Cast, qui soit le plus générique possible.

        // Méthode qui permet d'extraire les objets d'une collection.
        // Valable à partir de Framework .NET 2.0
        // On peut mettre cette méthode dans une classe d’aide(Helper)
        // de facon à l'appeler ailleur pour tout objet qui contient
        // une collection IEnumerable (listBox,)
        IEnumerable<T> Cast<T>(IEnumerable items)
        {
            foreach (object item in items)
                yield return (T)item;
        }

Dans l’exemple suivant, j’utilise une class nommé Personne comme type avec deux propriétés, à savoir : Nom et Prenom. L’utilisation d’un objet string ou autre est possible aussi (voir l’exemple dans le code complet).
Voila le code dans sa totalité.

Merci Éric pour tes idées :

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Collections;
using System.Windows.Forms;

namespace Yield_SelectedItems
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();

            List<Personne> personnes = new List<Personne>();
            personnes.Add(new Personne("Hugo", "Victor"));
            personnes.Add(new Personne("Zola", "Emile"));
            personnes.Add(new Personne("Dupont", "Thomas"));
            personnes.Add(new Personne("Dupond", "Daniel"));
            personnes.Add(new Personne("Super Dupond", "Daniel"));

            listBox1.Items.Clear();
            listBox1.Items.AddRange(personnes.ToArray());

        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Récupérer que les objets sélectionnés
            List<Personne> maSelections = new List<Personne>(Cast<Personne>(listBox1.SelectedItems));

            // On créer un objet list de type (chaine de caractère) pour générer
            // avec la méthode Join un saut de ligne facilement, sans avoir à 
            // gérer le premier ou le dernier retour chariot de trop.
            List<string> s = new List<string>();
            foreach (Personne onePersonne in maSelections)
            {
                s.Add(string.Format("{0} {1}", onePersonne.Prenom, onePersonne.Nom));
            }
            String nomPrenom = string.Join("\r", s.ToArray());

            // On affiche le résultat.
            System.Windows.Forms.MessageBox.Show(nomPrenom);


            // Démo avec une list de string
            ListBox mesProduits = new ListBox();
            mesProduits.SelectionMode = SelectionMode.MultiExtended;
            mesProduits.Items.Clear();

            // J'alimente ma listbox
            List<string> listProduits = new List<string>();
            listProduits.Add("Produit A");
            listProduits.Add("Produit B");
            listProduits.Add("Produit C");
            listProduits.Add("Produit D");
            listProduits.Add("Produit E");
            mesProduits.Items.Clear();
            mesProduits.Items.AddRange(listProduits.ToArray());

            // Je sinule une sélection
            mesProduits.SelectedItems.Add(listProduits[0]);
            mesProduits.SelectedItems.Add(listProduits[3]);

            // On récupère les produits sélectionnés
            List<string> monChoix = new List<string>(Cast<string>(mesProduits.SelectedItems));

            // On les affiches.
            System.Windows.Forms.MessageBox.Show(string.Join("\r", monChoix.ToArray()));


            // Lol, plus simple. Comme quoi des fois...
            Personne[] essai2 = new Personne[listBox1.SelectedItems.Count * 2]; // Je double la taille pour tester le mode Append
            listBox1.SelectedItems.CopyTo(essai2, 0);
            listBox1.SelectedItems.CopyTo(essai2, 3); // Append mode
            List<string> s2 = new List<string>();
            foreach (Personne onePersonne in essai2)
            {
                s2.Add(string.Format("{0} {1}", onePersonne.Prenom, onePersonne.Nom));
            }
            // On les affiches.
            System.Windows.Forms.MessageBox.Show(string.Join("\r", s2.ToArray()));


            // Lol, plus simple. Comme quoi des fois...
            string[] essai3 = new string[mesProduits.SelectedItems.Count];
            mesProduits.SelectedItems.CopyTo(essai3, 0);
            List<string> soluce3 = new List<string>(essai3);
            // On les affiches.
            System.Windows.Forms.MessageBox.Show(string.Join("\r", soluce3.ToArray()));

        }


        // Méthode qui permet d'extraire les objets d'une collection.
        // Valable à partir de Framework .NET 2.0
        // On peut mettre cette méthode dans une classe d’aide(Helper)
        // de facon à l'appeler ailleur pour tout objet qui contient
        // une collection IEnumerable (listBox,)
        IEnumerable<T> Cast<T>(IEnumerable items)
        {
            foreach (object item in items)
                yield return (T)item;
        }

    }


    class Personne
    {
        private string _nom;
        private string _prenom;

        public Personne()
        {
        }

        public Personne(string nom, string prenom)
        {
            Nom = nom;
            Prenom = prenom;
        }

        public string Nom
        {
            get { return _nom; }
            set { _nom = value; }
        }

        public string Prenom
        {
            get { return _prenom; }
            set { _prenom = value; }
        }

        // l'override de la méthode string est utilisé pour populer le listbox.
        public override string ToString()
        {
            return string.Format("{0} {1}", Nom, Prenom);
        }
    }

}

Aucun commentaire:

Enregistrer un commentaire

Membres