Pergunta

Gosto de programação defensiva. Eu odeio uma exceção ao arremesso, mas esse não é o assunto da minha pergunta.

Adaptei uma extensão ao LINQ para poder executar uma ordem com um nome de coluna

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

Com programação defensiva, esse método retorna o enumerável dado se o nome da coluna não for válido.

Agora eu preciso realizar um classificação secundária com então. Então eu preciso dessa assinatura:

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

Eu preciso devolver um eu ordenado. Meu problema é manter meu recurso de programação defensiva: devo devolver o conjunto fornecido é o nome da coluna é inválido.

Existe uma maneira limpa de fazer isso? Tudo o que estou pensando são tipo de truques:

  • Use a reflexão para encomendar pela primeira propriedade encontrada, o que é arriscado porque a propriedade pode não estar classificada
  • Implementar minha própria ordem de referência, o que também é arriscado porque eu executo pedidos em iQueryable ou Ilist, depois realizo outras operações do LINQ, por isso temo os efeitos colaterais.

E conselho / sugestão? Obrigado

Foi útil?

Solução

Você pode fazer qualquer pedido. Se a coluna não existir, deixe sua entrada enumerável como era antes. Para fazer isso, crie o seletor de chaves que retorne o mesmo valor para todos os elementos.

Consultar exemplo:

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 em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top