Filtrable generic list

Contenu du snippet

les List<T> c'est bien, mais le probleme, c'est pour les classer et filtrer par une propriété du type T !
j'ai donc produit cette classe qui permet le classement sur les propriétés du type de la collection, et surtout le filtrage du genre "where x>4 and l like 'wazaa' ".

Source / Exemple :


using System;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace System.Collections.Generic.Filtred
{
    [Serializable]
    public class FiltrableList<T>                                                                       
    {
        #region Fields
        private Type theType;
        private List<T> _List;
        private List<T> _FiltredList;
        private List<FilterValue> _Filters;
        #endregion

        #region Properties
        public List<T> List                                                                             
        {
            get { return _List; }
            set { _List = value; }
        }
        public List<FilterValue> Filters                                                                
        {
            get { return _Filters; }
            set { _Filters = value; } 
        }
        [XmlIgnore]
        public List<T> FiltredList                                                                      
        {
            get { return _FiltredList; }
        }
        #endregion
        
        #region Constructor
        public FiltrableList()                                                                          
        {
            _List = new List<T>();
            _FiltredList = new List<T>();
            _Filters = new List<FilterValue>();
            theType = typeof(T);
        }
        #endregion

        #region Public Methods
        public void FilterBy(string Property, object Value)                                             
        { _FiltredList = FilterBy(Property, Value, FilterComparaison.Equal, _List); }
        public void FilterBy(string Property, object Value, FilterComparaison Comp)                     
        { _FiltredList= FilterBy(Property, Value, Comp, _List); }
        public void ApplyFilters()                                                                      
        {
            _FiltredList = _List;
            foreach (FilterValue fv in _Filters)
                _FiltredList = FilterBy(fv.Property, fv.Value, fv.FilterComparaison,_FiltredList);
        }

        public void SortListBy(string Property)                                                         
        { SortBy(Property, SortDirection.Asc, _List); }
        public void SortListBy(string Property, SortDirection direction)                                
        { SortBy(Property, direction, _List); }
        public void SortFiltredListBy(string Property)                                                  
        { SortBy(Property, SortDirection.Asc, _FiltredList); }
        public void SortFiltredListBy(string Property, SortDirection direction)                         
        { SortBy(Property, direction, _FiltredList); }
        #endregion

        #region Private Methods
        private void SortBy(string Property, SortDirection direction,List<T> list)                      
        {
            System.Reflection.PropertyInfo pi=theType.GetProperty(Property);
            if (pi == null) throw new Exception("Property " + Property + " does not exists in class " + typeof(T));
            list.Sort(new Comparison<T>(
                delegate(T t1, T t2)
                { return ((IComparable)pi.GetValue(t1, null)).CompareTo(pi.GetValue(t2, null)) * (int)direction; }
                ));
        }
        private List<T> FilterBy(string Property, object Value, FilterComparaison Comp, List<T> list)   
        {
            System.Reflection.PropertyInfo pi = theType.UnderlyingSystemType.GetProperty(Property);
            if (pi == null) throw new Exception("Property " + Property + " does not exists in class " + typeof(T));
            return list.FindAll(new Predicate<T>(delegate(T o)
                {
                    object theValue = pi.GetValue(o, null);
                    int res = ((IComparable)theValue).CompareTo(Convert.ChangeType(Value, theValue.GetType()));
                    switch (Comp)
                    {
                        case FilterComparaison.Inf: return res < 0;
                        case FilterComparaison.InfEqual: return res <= 0;
                        case FilterComparaison.Sup: return res > 0;
                        case FilterComparaison.SupEqual: return res >= 0;
                        case FilterComparaison.Like:
                            return ((string)theValue).ToLower().Contains(((string)Value).ToLower());
                        case FilterComparaison.NotLike:
                            return !((string)theValue).ToLower().Contains(((string)Value).ToLower());
                        default: return res == 0;
                    }
                }
                ));
        }
        #endregion

    }

    [Serializable]
    public class FilterValue                                                                            
    {
        #region Fields
        private string _Property;
        private object _Value;
        private FilterComparaison _FilterComparaison;
        #endregion

        #region Properties
        public string Property                                                                          
        { get { return _Property; } set { _Property = value; } }
        public object Value                                                                             
        { get { return _Value; } set { _Value = value; } }
        public FilterComparaison FilterComparaison                                                      
        { get { return _FilterComparaison; } set { _FilterComparaison = value; } }
        #endregion

        #region Constructors
        public FilterValue(string Property, object Value, FilterComparaison Comp)                       
        {
            _Property = Property;
            _Value = Value;
            _FilterComparaison = Comp;
        }
        public FilterValue(string Property, object Value)                                               
        {
            _Property = Property;
            _Value = Value;
            _FilterComparaison = FilterComparaison.Equal;
        }
        #endregion
    
    }

    public enum FilterComparaison                                                                       
    {
        Inf, Sup, Equal, Like, InfEqual, SupEqual, NotLike
    }
    
    public enum SortDirection                                                                           
    {
        Asc = 1, Desc = -1
    }
}

Conclusion :


pour l'instant j'ai exposé dans cette classe tout ce qui me paraitrait important, mais il me serais tres utile d'avoir des commentaires pour connaitre l'utilisation commune que l'on pourrait faire de cette classe pour optimiser le code dans ce sens !
exemple d'utilisation :
class Program
{
static void Main(string[] args)
{
FilterableList<test> fList = new FilterableList<test>();
for (int i = 0; i < 10; i++)
fList.List.Add(new test("a" + i.ToString(), i));
fList.Filters.Add(new FilterValue("MyInt", 2, FilterComparaison.Sup));
fList.ApplyFilters();
foreach (test t in fList.FiltredList)
Console.Write(t.ToString());
//3,4,5,6,7,8,9
Console.WriteLine();
Console.ReadKey(false);
fList.Filters.Add(new FilterValue("MyInt", 5, FilterComparaison.InfEqual));
fList.ApplyFilters();
foreach (test t in fList.FiltredList)
Console.Write(t.ToString());
//3,4,5
Console.WriteLine();
Console.ReadKey(false);
fList.SortFiltredListBy("MyInt", SortDirection.Desc);
foreach (test t in fList.FiltredList)
Console.Write(t.ToString());
//5,4,3
Console.WriteLine();
Console.ReadKey(false);
fList.FilterBy("MyString", "a", FilterComparaison.Like);
foreach (test t in fList.FiltredList)
Console.Write(t.ToString());
//all
Console.WriteLine();
Console.ReadKey(false);
foreach (test t in fList.List)
Console.Write(t.ToString());
//all
Console.WriteLine();
Console.ReadKey(false);
fList.SortListBy("MyInt", SortDirection.Desc);
foreach (test t in fList.List)
Console.Write(t.ToString());
//all reversed
Console.ReadKey(false);
}
}

public class test
{
private string _MyString;
private int _MyInt;
public string MyString
{ get { return _MyString; } set { _MyString = value; } }
public int MyInt
{ get { return _MyInt; } set { _MyInt = value; } }
public test(string s, int i) { MyString = s; MyInt = i; }
public override string ToString()
{ return MyInt.ToString(); }
}

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.