3 votes

Création d'une fonction de tri pour une liste générique

J'ai une méthode pour trier les listes génériques par les champs de l'objet :

public static IQueryable<T> SortTable<T>(IQueryable<T> q, string sortfield, bool ascending)
{
    var p = Expression.Parameter(typeof(T), "p");

    if (typeof(T).GetProperty(sortfield).PropertyType == typeof(int?))
    {
        var x = Expression.Lambda<Func<T, int?>>(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    else if (typeof(T).GetProperty(sortfield).PropertyType == typeof(int))
    {
        var x = Expression.Lambda<Func<T, int>>(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    else if (typeof(T).GetProperty(sortfield).PropertyType == typeof(DateTime))
    {
        var x = Expression.Lambda<Func<T, DateTime>>(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
    }
    // many more for every type
    return q;
}

Existe-t-il un moyen de réduire ces ifs à une seule déclaration générique ? Le principal problème est que pour la partie Expression.Lambda<Func<T, int>> Je ne sais pas comment l'écrire de manière générique.

3voto

dtb Points 104373

Si vous élargissez Queryable.OrderBy à sa définition, il n'est pas nécessaire d'utiliser la surcharge générique de l'option Expression.Lambda :

public static IQueryable<T> SortTable<T>(
    IQueryable<T> q, string sortfield, bool ascending)
{
    var p = Expression.Parameter(typeof(T), "p");
    var x = Expression.Lambda(Expression.Property(p, sortfield), p);

    return q.Provider.CreateQuery<T>(
               Expression.Call(typeof(Queryable),
                               ascending ? "OrderBy" : "OrderByDescending",
                               new Type[] { q.ElementType, x.Body.Type },
                               q.Expression,
                               x));
}

0voto

Nayan Points 1817

Ça ne va pas marcher ?

    public static IQueryable<T> SortTable<T>(IQueryable<T> q, string sortfield, bool ascending)
    {
        var type = typeof(T).GetProperty(sortfield).PropertyType;
        var p = Expression.Parameter(typeof(T), "p");
        var x = Expression.Lambda<Func<T, type> >(Expression.Property(p, sortfield), p);
        if (ascending)
            q = q.OrderBy(x);
        else
            q = q.OrderByDescending(x);
        return q;
    }

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X