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

C# Discussion :

Meilleur usage de Icomparer


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut Meilleur usage de Icomparer
    Bonjour

    Je me pose quelques questions sur le meilleurs usage de l'interface Icomparer et je pense que je n'ai pas bien capté qq chose

    J'ai une classe adresse C_Adr
    Pour pouvoir trier des liste de C_Adr, j'ai défini (en dehaos de C_Adr) une Classe C_AdrComparer héritant de IComparer

    Donc quand je veux faire un tri, j'appelle

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    List.Sort(new C_AdrComparer());
    Mais je dois aussi pouvoir comparer une adresse A avec une adresse B

    Je peux evidemment utiliser une instance de C_AdrComparer et comparer A et B

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    C_AdrComparer Acompare=new C_AdrComparer();
    int dif=Acompare(A,B);
    Mais j'aurais préféré utiliser une methode CompareTo() définie dans ma classe Adresse

    Donc ma question :
    Quelle est la methode la plus elégante pour definir une seule methode de comparaison que je pourrais utiliser a la fois dans une Methode CompareTo et dans un Sort()

    Actuellement je cree une instance de C_AdrComparer dans une methode publique CompareTo de C_Adr

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        public int CompareTo(CDB_Adresse B)
        {
          C_AdrComparer cmp = new C_AdrComparer();
          return cmp.Compare(this,B);
        }
    Est ce la meilleure maniere ?
    Merci de vos conseils

  2. #2
    Membre Expert
    Avatar de Sehnsucht
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Octobre 2008
    Messages
    847
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Lot et Garonne (Aquitaine)

    Informations professionnelles :
    Activité : Développeur .NET

    Informations forums :
    Inscription : Octobre 2008
    Messages : 847
    Par défaut
    Bonsoir,

    Tu peux faire implémenter à ta classe l'interface IComparable ou sa version générique, qui présente une méthode CompareTo, et qui sera utilisée par défaut lors d'appel de méthode de tri (comme List.Sort)

    Cordialement !

  3. #3
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    En complément de Sehnsucht, on peut également utiliser la surcharge de la méthode Sort qui accepte un délégué indiquant comment trier les éléments. Si jamais il était impossible d'implémenter IComparable sur la classe (je ne pense pas que le cas puisse se présenter, mais bon ^^)

    Cela donnerait par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    public class Adresse
    {
        ...
        public static Int32 Compare(Adresse x, Adresse y)
        {
            // Comparaison des adresses
            ...
        }
    }
    Et pour le tri
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    listeAdresse.Sort(Adresse.Compare);

  4. #4
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Merci Sehnsucht et Stormimonn

    Oui effectivement le plus normal c'est d'implemeter Icomparable
    Alors que moi je l'avais fait a l'envers

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Une petite précision...

    Implémenter IComparable, ou utiliser un IComparer, ce n'est pas exactement la même chose. Si IComparable est implémentée, elle sera utilisée par le comparateur par défaut (Comparer<T>.Default). C'est une comparaison "intrinsèque" entre 2 instances de ta classe. Le problème, c'est que cette approche n'est pas très souple...

    Par exemple, tu pourrais vouloir, selon les cas, trier une liste selon différents critères. Ce n'est pas possible en utilisant seulement IComparable, car ça ne définit qu'un seul ordre possible. Pour gérer ça, tu es obligé d'utiliser un IComparer (ou un delegate Comparison, comme l'a indiqué StormimOn)

    Bref, implémenter IComparable n'a de sens que s'il existe un ordre intrinsèque entre les objets de ta classe. Si c'est juste pour faire un tri selon des critères changeants, ça ne sert pas à grand chose.

    Au passage, pour faciliter les choses, tu peux aussi implémenter les opérateurs de comparaison sur ta classe, c'est plus pratique que d'appeler CompareTo

  6. #6
    Membre expérimenté
    Profil pro
    Mangeur de gauffre
    Inscrit en
    Octobre 2007
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Mangeur de gauffre

    Informations forums :
    Inscription : Octobre 2007
    Messages : 4 413
    Par défaut
    Citation Envoyé par Tomlev
    Bref, implémenter IComparable n'a de sens que s'il existe un ordre intrinsèque entre les objets de ta classe. Si c'est juste pour faire un tri selon des critères changeants, ça ne sert pas à grand chose.
    Merci pour cette confirmation Tomlev, c'est effectivement ce que j'avais conclu mais in fine Icomparable peut etre utilisé pour definir un comparateur d'équivallence par défaut et qui peut accessoirement servir a certain tris
    Et cela n'exclut pas la definition de compareur accessoire permettants d'autres tris ou evaluations.

    Au passage, pour faciliter les choses, tu peux aussi implémenter les opérateurs de comparaison sur ta classe, c'est plus pratique que d'appeler CompareTo
    Plus pratique ?
    Si tu pense a surcharger les opérateurs < > <= >=, je trouve cela au contraire beaucoup plus fastidieux
    - D'une part pour l'ecriture du codes spécifique a chaque opérateur
    - D'autre part le test d'un int <1 >1 ou 0 ne me semble pas plus complexe que le test d'un booleen au retour de <= par exemple

    Mais je n'ai peut etre pas bien compris ce que tu suggerais ?

  7. #7
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Citation Envoyé par olibara Voir le message
    Plus pratique ?
    Si tu pense a surcharger les opérateurs < > <= >=, je trouve cela au contraire beaucoup plus fastidieux
    Ben c'est pas très long... après ça dépend si tu as souvent besoin de comparer des instances de cette classe. Si c'est juste à 1 ou 2 endroits, effectivement ça vaut sans doute pas le coup

    Citation Envoyé par olibara Voir le message
    - D'une part pour l'ecriture du codes spécifique a chaque opérateur
    Bah Il suffit d'appeler CompareTo dans chaque opérateur...

    Citation Envoyé par olibara Voir le message
    - D'autre part le test d'un int <1 >1 ou 0 ne me semble pas plus complexe que le test d'un booleen au retour de <= par exemple
    Question de point de vue... perso je trouve beaucoup plus clair ce code :

    Que celui-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if (a.CompareTo(b) < 0)
    Ca fait réfléchir une demi-seconde de moins quand tu le relis

Discussions similaires

  1. Les meilleurs cours et tutoriels C++
    Par Community Management dans le forum C++
    Réponses: 1
    Dernier message: 13/05/2015, 13h50
  2. Serveur mmo multithread meilleur usage
    Par skeud dans le forum Threads & Processus
    Réponses: 2
    Dernier message: 09/12/2013, 09h58
  3. Quel est le meilleur script PHP de portail (CMS) ?
    Par Lana.Bauer dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 187
    Dernier message: 18/10/2012, 07h45
  4. Réponses: 87
    Dernier message: 06/07/2011, 15h33

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