Pregunta

Me gusta la programación defensiva. Odio el lanzamiento de excepción, pero este no es el tema de mi pregunta.

Adapté una extensión a Linq para poder realizar un pedido con un nombre de columna

        public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> list, string sortExpression)

Con programación defensiva, este método devuelve el enumerable dado si el nombre de la columna no es válido.

Ahora necesito realizar un clasificación secundaria con entonces. Así que necesito esa firma:

        public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> list, string sortExpression)

Necesito devolver un iorderedenumerable. Mi problema es mantener mi función de programación defensiva: debo devolver el conjunto dado es que el nombre de la columna no es válido.

¿Hay una forma limpia de hacer esto? Todo lo que estoy pensando son un tipo de trucos:

  • Use la reflexión al orden por la primera propiedad encontrada, que es arriesgada porque la propiedad puede no estar a la clasificación
  • Implemente mi propio IOrderDenumerable, lo cual también es arriesgado porque realizo el pedido en IQueryable o Ilist, luego realizo otras operaciones de LINQ, por lo que temo los efectos secundarios.

Y consejo / sugerencia? Gracias

¿Fue útil?

Solución

Puede hacer cualquier pedido. Si la columna no existe, simplemente deje su entrada enumerable como era antes. Para hacer esto, cree un selector de clave que devuelva el mismo valor para todos los elementos.

Ver ejemplo:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Reflection;

static class Program
{
    public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> list, string sortExpression) where T : class
    {
        Func<T, Int32> keySelector = (elem) =>
        {
            PropertyInfo pi = typeof(T).GetProperty(sortExpression, typeof(Int32));
            if (pi == null)
                return 0; // return the same key for all elements

            return Int32.Parse(pi.GetValue(elem, null).ToString());
        };

        return list.OrderBy(keySelector);
    }

    static void Main(string[] args)
    {
        // Create an array of strings to sort.
        string[] fruits = { "apricot", "orange", "banana", "mango", "apple", "grape", "strawberry" };

        // Sort by "column" Length
        foreach (string s in fruits.OrderBy<string>("Length"))
            Console.WriteLine(s);
        Console.WriteLine();

        // Sort by non-existing column
        foreach (string s in fruits.OrderBy<string>("ength"))
            Console.WriteLine(s);
        Console.ReadKey();
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top