IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

[2.0] IList, utilisation des prédicats de recherche


Sujet :

Framework .NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Louis-Guillaume Morand
    Homme Profil pro
    Cloud Architect
    Inscrit en
    Mars 2003
    Messages
    10 839
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Cloud Architect
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 10 839
    Par défaut [2.0] IList, utilisation des prédicats de recherche
    supposons que j'ai des collections d'objets. on va dire des collections Classe, contenant des objets Eleve.

    J'aimerai savoir comment le plus simplement et le plus proprement savoir si une class contient tel ou tel élève selon le nom de cette eleve.

    Actuellement, je fais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach(Eleve elv in Class)
      if( elv.Nom = "toto")
         return true;
    Sauf que ceci n'est p-e pas la manière la plus propre.

    Maintenant, au lieu d'avoir Class heritant de CollectionBase, je l'ai fait heriter de List ce qui me donne plein de méthode marrantes.
    Contains, Exists, Find, etc

    Eleve peut avoir plusieurs propriétés: nom, prenom, etc
    et donc je ne pense pas pouvoir utiliser .Contains.

    Par contre, Exists qui prend un prédicat plus avancé pourrait marcher. Mais voilà. J'ai un peu de mal avec cette notion.

    de ce que je comprend, je dois faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    return Class.Exists(monpredicat);
    ...
    private static bool monpredicat(Eleve elv)
    {
        return (elv.Nom.Equals("toto"))? true: false;
    }
    Déjà, est-ce réellement plus propre? Ensuite, comment rendre "toto" dynamique.

    en gros quelque chose comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    return Class.Exists(monpredicat("toto"));
    ...
    private static bool monpredicat(Eleve elv, object nom)
    Je découvre totalement ce genre de choses. Mais comme je n'ai jamais utilisé bcp des fonctionnalités des collections, je me dis qu'il est p-e temps de voir ce qu'on peut faire ou non.
    merci d'avance à ceux qui pourront éclairer ma faible lanterne

  2. #2
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Tu peux le faire avec une méthode anonyme.
    Par exemple, pour savoir s'il existe un éléève ayant un nom donné :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public bool ExisteUnEleveDeNom(string nom)
    {
      Eleve monEleve =  taListe.Find(
                          delegate(Eleve e) { return e.Nom == nom; } // la fn anonyme (ici un prédicat, i.e. une fonction qui prend un param et renvoie un bool)
                         );
      return monEleve != null;
    }
    (pas facile de trouver une indentation qui facilite la compréhension )
    En effet, Find renvoie null (plus précisément default(T)) s'il ne trouve rien.

    Je l'ai fait ici avec une méthode anonyme, qui a l'avantage par rapport aux méthodes nommées de pouvoir utiliser les variables (ici "nom") présentes dans le bloc { } qui la contient. SirJulio avait très bien expliqué ça il y a quelques temps sur le forum C#, tu peux fouiller ses post.

  3. #3
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Tu peux aussi faire ca :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public static Predicate<Eleve > monpredicat(string nom) {
        return delegate(Eleve elv) {
            return elv.Nom == nom;
        };
    }
     
    return Class.Exists(monpredicat("nom"));

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  4. #4
    Rédacteur
    Avatar de Louis-Guillaume Morand
    Homme Profil pro
    Cloud Architect
    Inscrit en
    Mars 2003
    Messages
    10 839
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Cloud Architect
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 10 839
    Par défaut
    la solution de pvialiatte est nickel (et j'étais pas loin dans mes essais)
    Par contre, maintenant, je me demande ce qui est le plus propre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach (UserDeal ud in Deals)
              if (ud.DealName == dealName)
                   return true;
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    return Deals.Exists(searchNom(dealName));
    ...
    public static Predicate<UserDeal> searchNom(string nom)
    {
          return delegate(UserDeal ud)
          {
                return ud.DealName == nom;
           };
    }
    je sais que je peux faire des prédicats bcp plus complexes mais là dans ce cas, est-ce plus intéressant d'utiliser la deuxième méthode (performance ou autre?). J'avoue que maintenant que la solution 2 prend plus de lignes, je ne suis plus sûr de ce qui est bon

  5. #5
    Expert confirmé

    Avatar de Philippe Vialatte
    Homme Profil pro
    Architecte technique
    Inscrit en
    Juillet 2004
    Messages
    3 029
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Juillet 2004
    Messages : 3 029
    Par défaut
    Perso, j'utilise la methode du predicate si je dois utiliser ma fonction dans 2 ou 3 endroits au moins...

    Sinon, si c'est du one shot, le foreach est tres bien

    Il faudrait regarder le code IL genere, mais je pense que niveau perf, c'est kif kif

    Mon Blog

    The Cake is still a lie !!!



    Vous voulez contribuer à la rubrique .NET ? Contactez-moi par MP.
    Vous voulez rédiger des articles pour la rubrique .NET ? Voici la procédure à suivre.

  6. #6
    Rédacteur
    Avatar de SaumonAgile
    Homme Profil pro
    Team leader
    Inscrit en
    Avril 2007
    Messages
    4 028
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Team leader
    Secteur : Conseil

    Informations forums :
    Inscription : Avril 2007
    Messages : 4 028
    Par défaut
    Oui les performances sont équivalentes vu que le code anonyme est traité par le compilateur (transformé en code non-anonyme ^^), de sorte que le jitter n'ait plus rien à faire.
    Besoin d'un MessageBox amélioré ? InformationBox pour .NET 1.1, 2.0, 3.0, 3.5, 4.0 sous license Apache 2.0.

    Bonnes pratiques pour les accès aux données
    Débogage efficace en .NET
    LINQ to Objects : l'envers du décor

    Mon profil LinkedIn - MCT - MCPD WinForms - MCTS Applications Distribuées - MCTS WCF - MCTS WCF 4.0 - MCTS SQL Server 2008, Database Development - Mon blog - Twitter

  7. #7
    Membre Expert Avatar de Guulh
    Homme Profil pro
    Inscrit en
    Septembre 2007
    Messages
    2 160
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Citation Envoyé par Louis-Guillaume Morand Voir le message
    la solution de pvialiatte est nickel (et j'étais pas loin dans mes essais)
    Par contre, maintenant, je me demande ce qui est le plus propre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach (UserDeal ud in Deals)
              if (ud.DealName == dealName)
                   return true;
    L'avantage de cette solution, c'est qu'elle fonctionne pour n'importe quel IEnumerable<Deal>. Alors que se baser sur les fonctionnalités de la List nécessite, évidemment, de bosser avec une List.
    Un inconvénient des méthodes anonymes est l'impossibilité de modifier le contenu des fonctions qui les contiennent en cours de déboguage. Pas de problème si la fn est nommée.

    Après, d'un point de vue perf, comme l'a expliqué SaumonAgile, c'est pareil. Mais je dois avouer que d'un point de vue très subjectif, ça me plait beaucoup, parce que ça reprend des concepts de C++ sans avoir à créer une classe avec un operator() à chaque fois. Le compilo fait ça tout seul.

    En anonyme :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    return Deals.Contains(delegate(Deal d) { return d.DealName == dealName; });
    J'ajoute que Linq change encore plein de choses, en proposant une syntaxe qui facilite les fonctionnalités offertes par ces méthodes. Les méthodes d'extension aussi permettront de faire du code plus court, plus beau, plus propre

  8. #8
    Membre émérite
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    547
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 547
    Par défaut
    Salut,

    le gros avantage de la methode anonyme, c'est qu'elle sait capturer ses parametres de recherche toute seul (Loué soit le magie de csc =p) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
                List<string> _list = new List<string>(new string[] {"Toto", "Tata", "Tutu"});
     
                string str = Console.ReadLine();
     
                bool b = _list.Exists(
                    delegate(string s)
                    {
                        return str == s;
                    });
                Console.WriteLine("Occurence trouvée : " + (b ? "Oui" : "Non"));
    Apres anonyme ou nommé, c'est plus un probleme de presentation qu'autre chose, les perfs sont identiques (les methodes anonymes sont transformés en methodes nommées par csc, le runtime ne connaissant pas du tout la notion de meth anonymes). Pour ma part, j'aime beaucoup les methodes anonymes surtout pour les foncteurs de collections, cela permet d'avoir sous les yeux, ta methode de match.

    Juste comme limite, l'anonyme sur des fonctions amenées a etre reappelées souvent et en divers endroits, c'est pas top (comme dit au dessus), et les problemes de captures des variables locales par la methodes dans des contextes multithreadés.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 20/09/2010, 11h05
  2. Utilisation des invariants pour la recherche des images par le contenu
    Par sarrainf dans le forum Traitement d'images
    Réponses: 3
    Dernier message: 27/03/2009, 13h09
  3. Réponses: 0
    Dernier message: 23/01/2009, 09h12
  4. Utiliser des champs de recherche pour une valeur calculée.
    Par MasterJul dans le forum SharePoint
    Réponses: 0
    Dernier message: 08/02/2008, 12h47
  5. Réponses: 5
    Dernier message: 20/09/2006, 13h16

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo