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 :

Utilisations de filtres


Sujet :

C#

  1. #1
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut Utilisations de filtres
    Bonjour,

    j'aurais une petite question à vous poser. Voila , j'ai un objet utilisateur qui possedent une collection de filtres defini comme suit :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    public abstract class UserProvider : IUser
        {
     
         public FilterLibrary Filters;
       }
    FilterLibrary etant une liste de FilterProvider qui est une classe abstraite.
    Cette classe est tres pratique car elle me permet de centraliser les points communs a tous les filtres.

    Je derive cette classe pour obtenir un filtre precis pour par exemple extraire un catalogue :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     public class CatalogItemFilter : FilterProvider
        {
            public int NodeLevel { get; set; }
            public bool ShowSubTree { get; set; }
     
            public CatalogItemFilter()
            {
     
            }
     
        }
    Jusqu'ici point de souci, apr contre lorsque j'utilise ce systeme je me retrovue avec quelquechose qui n'est pas tres joli :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ((CatalogItemFilter)CurrentUser.Filters_
                _[typeof(CatalogItemFilter)]).NodeLevel;
    Pour recuperer mon filtre dans ma liste je le choisis en fonction de son type, cela est tres bien car si je veux un filtre sur le catalog, je lui dit et il me le trouve. Apr contre du fait de cette construction je suis obligé de le recaster car la liste contenu dans FilterLibrary est une lsite de filterLibrary.

    Manque je quelquechose dans cette architecture? Je trouve cela malheureux d'avoir a spécifier 2 fois mon type..

    Merci d'avance de vos idées..

  2. #2
    Rédacteur
    Avatar de Paul Musso
    Profil pro
    Inscrit en
    Août 2008
    Messages
    368
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Août 2008
    Messages : 368
    Par défaut
    Bonjour,

    J'ai tenté la solution de l'inférence de type mais le résultat n'est pas terrible. D'abord parce que les opérateurs ne supportent pas les generics, et de 2, tu ne passes seulement que le type de la classe et non une instance de la classe.

    Le meilleur que j'ai pu faire ressemble à ça (c'est pas terrible mais il n'y a plus de cast) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
            public T get<T> (T type) where T : class
            {
                T provider = default(T);
                foreach (var objet in liste)
                {
                    if (objet.GetType().Equals(type.GetType()))
                        provider = objet as T;
                }
                return provider;
            }
    Cette méthode est à mettre dans la classe FilterLibrary. A l'utilisation ça donne ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
                var valeur = CurrentUser.Filters.get(new CatalogItemFilter()).NodeLevel;
    C'est bizarre je sais ...

  3. #3
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut
    Effectivement!

    Merci en tout cas de ton aide, j'essaierais de farfouiner par lá demain!

  4. #4
    Membre émérite
    Inscrit en
    Octobre 2006
    Messages
    587
    Détails du profil
    Informations personnelles :
    Âge : 39

    Informations forums :
    Inscription : Octobre 2006
    Messages : 587
    Par défaut
    Je suis pas sur d'avoir compris le problème...

    Ta collection n'est pas fortement typée ?

    Pourquoi utilise un objet de type Type dans un indexeur ?

  5. #5
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut
    Parce que ce à quoi j'accede dans ma liste est un filterProvider.Or ce que je mets dedans est est un classe qui derive de ce filterprovider. Et quand j'ai besoin d'acceder au proprietes de cette qui classe dérivée, je me heurte au 'probleme' ci dessus.

    Maintenant, j'y accede par type car je trouve cela plus pratique. Je suis dans une page ou je vais vouloir afficher un tableau base sur des categories, je vais donc utiliser le filtre categorie, et pour le retrouver c'est simple je regarde dans ma liste de filtre et je prends le filtre categorie. Si dans une autre page, je me retrouvais face a quelquechose de similaire, je ferais de meme.

    Ma liste est fortement typee, mais pas jusqu'au bout. Apres je ne suis pas sur d'avoir completement raison non plus de faire comme ca... si tu as des idées , n'hésites pas, c'est du prototypage là...

  6. #6
    Rédacteur
    Avatar de Paul Musso
    Profil pro
    Inscrit en
    Août 2008
    Messages
    368
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Août 2008
    Messages : 368
    Par défaut
    Mouarf, des fois je suis un peu débile. A vouloir utiliser les nouveaux trucs, j'en oublie un peu le problème, cette fonction devrait t'aider :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
            public T get<T>() where T : class
            {
                foreach (var objet in liste)
                {
                    if (objet.GetType().Equals(typeof(T)))
                        return objet as T;
                }
                return null;
            }
    A l'utilisation, ça donne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    var valeur = CurrentUser.Filters.get<CatalogItemFilter>().NodeLevel;
    Simple non ?

  7. #7
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut
    Super! C'est exactement cela.

    Merci une fois encore Paul. Je commence juste à developper à ce niveau lá , jusqu'á présent, je m'étais contenté d'utiliser ces listes...

    donc prépares toi tu risques d'en voir quelques autres passer...

    a+ tout le monde,

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Si tu utilises C# 3, il existe une méthode d'extension qui correspond au "get" de Paul : "OfType. cf http://msdn.microsoft.com/fr-fr/library/bb360913.aspx

    Ca nécessite que FilterLibrary soit une IEnumerable, ce qui est pas plus mal pour une collection d'objets

  9. #9
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut
    C'est une bonne méthode mais pour mon cas précis je vais rester avec la méthode de Paul, en effet, je ne veux récuperer qu'un seul objet de ma liste.

    Par contre, dans le futur , je le note dans un coin de ma tête...

    merci a+,

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Tu n'en veux qu'un ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    FilterLibrary.First(ifilter => ifilter is CatalogItemFilter);
    Si par exemple FilterLibrary est un IEnumerable<IFilter>.

  11. #11
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut
    J'avoue etre un peu perdu lá... Voilá ce que j'ai fait jusqu'à présent :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    public class FilterLibrary : IEnumerable<IFilter>
        {
     
            public FilterLibrary()
            {
                inner = new LazyList<FilterProvider>();
            }
     
     
            private LazyList<FilterProvider> inner;
     
     
     
            public FilterProvider Find(Type type)
            {
                FilterProvider returnvalue = null;
                foreach (FilterProvider f in inner)
                {
                    if (f.GetType() == type)
                    {
                        returnvalue = f;
                        break;
                    }
                }
                return returnvalue;
            }
     
            public bool HasItem(Type type)
            {
                bool returnvalue = false;
                foreach (FilterProvider f in inner)
                {
                    if (f.GetType() == type)
                    {
                        returnvalue = true;
                        break;
                    }
                }
                return returnvalue;
            }
     
            public FilterProvider this[Type type]
            {
                get { return Find(type); }
            }
     
            public void Add(FilterProvider item)
            {
                inner = inner ?? new LazyList<FilterProvider>();
                inner.Add(item);
            }
     
            public T get<T>() where T : class
            {
                foreach (var obj in inner)
                {
                    if (obj.GetType().Equals(typeof(T)))
                        return obj as T;
                }
                return null;
            }
     
            public IEnumerator<IFilter> GetEnumerator()
            {
                return new FilterEnum(this.inner);
            }
     
        }

    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    public class FilterEnum : IEnumerator<IFilter>
        {
            public IList<IFilter> _filter;
     
        // Enumerators are positioned before the first element
        // until the first MoveNext() call.
        int position = -1;
     
        public FilterEnum(IList<IFilter> list)
        {
            _filter = list;
        }
     
        public bool MoveNext()
        {
            position++;
            return (position < _filter.Count);
        }
     
        public void Reset()
        {
            position = -1;
        }
     
        public object Current
        {
            get
            {
                try
                {
                    return _filter[position];
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
        public void Dispose()
        {
            this._filter = null;
        }
    }
    et je me heurte a des probleme d'implementation d'interface..


    'Library.Model.Filter.FilterEnum' does not implement interface member 'System.Collections.IEnumerator.Current'. 'Library.Model.Filter.FilterEnum.Current' cannot implement 'System.Collections.IEnumerator.Current' because it does not have the matching return type of 'object'.

    or pour moi : "public object Current" devrait renvoyer un object non?

    Je nage pas mal...

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Hmmm... a mon avis, plutôt que de créer un enumérateur à la main, tu devrais plutôt faire hériter FilterLibrary de LazyList<Filterprovider>.
    Tu aurais alors juste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class FilterLibrary : LazyList<FilterProvider>
    {
     public FilterProvider Find(Type type)
      {
        return base.First(f => f.GetType() == t);
      }
      public bool HasItem(Type t)
      {
        return (this.Find(t) != null);
      }
    }
    De toutes façon, tu as intérêt à ce que FilterLibrary implémente IEnumerable et/ou IQueryable et/ou IList ... de façon à pouvoir la manipuler facilement.

  13. #13
    Rédacteur
    Avatar de Paul Musso
    Profil pro
    Inscrit en
    Août 2008
    Messages
    368
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Août 2008
    Messages : 368
    Par défaut
    Citation Envoyé par Arthis Voir le message
    J'avoue etre un peu perdu lá... Voilá ce que j'ai fait
    et je me heurte a des probleme d'implementation d'interface..


    'Library.Model.Filter.FilterEnum' does not implement interface member 'System.Collections.IEnumerator.Current'. 'Library.Model.Filter.FilterEnum.Current' cannot implement 'System.Collections.IEnumerator.Current' because it does not have the matching return type of 'object'.

    or pour moi : "public object Current" devrait renvoyer un object non?

    Je nage pas mal...
    Il faut aussi que tu implémente la propriété Current qui renvoit un IFilter :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            FilterProvider IEnumerator<IFilter>.Current
            {
                get { throw new NotImplementedException(); }
            }
    Sinon, je suis d'accord avec Guulh

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

    Informations forums :
    Inscription : Septembre 2007
    Messages : 2 160
    Par défaut
    Quand j'ai dit "IFilter", c'était un exemple, parce que je supposais que tous tes filtres implémentaient une interface du style "IFilter". En relisant la discussion, j'ai pas l'impression que ce soit le cas ; plutôt qu'une implémentation d'interface, c'est visiblement un héritage d'une classe abstraite "FilterProvider" qui a été retenue (Arthis, corrige moi si je me trompe).

    Mais d'ailleurs : ta collection n'a qu'un seul filtre de chaque type ?

  15. #15
    Membre Expert Avatar de Arthis
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    1 265
    Détails du profil
    Informations personnelles :
    Âge : 49
    Localisation : Italie

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 265
    Par défaut
    Non j'ai bien une interface IFilter mais pour l'instant j'utilisais surtout la classe abstraite filterProvider qui implementait cette interface. Je me sentais plus à l'aise avec le concept de classe abstraite que d'interface, car j'utilise beaucoup de proprietes et peu de methodes dans ces filtres...

    Sinon oui pour ta seconde question. Je pense que cette notion evoluera mais pour l'instant, je m'en sers de cette facon.

    Je vais regarder tout ce que vous me dites. Merci en tout cas à tous les deux de me guider !

Discussions similaires

  1. [TSMDBGrid] Utilisation des filtres
    Par Laurent Dardenne dans le forum Bases de données
    Réponses: 14
    Dernier message: 26/02/2007, 21h24
  2. [ JSP ] utilisation des filtres
    Par Pi2 dans le forum Servlets/JSP
    Réponses: 1
    Dernier message: 09/11/2006, 14h44
  3. [Débutant] Utilisation de filtres
    Par DelPiero dans le forum Access
    Réponses: 2
    Dernier message: 28/04/2006, 15h52
  4. Utiliser un Filtre sous Forms9i
    Par Challenger dans le forum Oracle
    Réponses: 22
    Dernier message: 20/05/2005, 09h22
  5. [TIBCLientDataSet] Utilisation des Filtres
    Par nico27 dans le forum Connexion aux bases de données
    Réponses: 4
    Dernier message: 24/06/2004, 14h22

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