Domanda

Mi piace la programmazione difensiva.Odio lanciare eccezioni, ma questo non è l'oggetto della mia domanda.

Ho adattato un'estensione a linQ per poter eseguire un ordine con un nome di colonna

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

Con programmazione difensiva, questo metodo restituisce l'enumerabile specificato se il nome della colonna non è valido.

Ora devo eseguire a ordinamento secondario con ThenBy.Quindi mi serve quella firma:

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

Devo restituire un IOrderedEnumerable.Il mio problema è mantenere la mia caratteristica di programmazione difensiva:Devo restituire il set specificato se il nome della colonna non è valido.

Esiste un modo pulito per farlo?Tutto quello a cui penso sono dei tipi di trucchi:

  • Utilizzare la riflessione per ordinare in base alla prima proprietà trovata, il che è rischioso perché la proprietà potrebbe non essere consentita per l'ordinamento
  • Implementa il mio IOrderedEnumerable, che è anch'esso rischioso perché eseguo ordini su IQueryable o IList, quindi eseguo altre operazioni LinQ, quindi temo gli effetti collaterali.

E un consiglio/suggerimento?Grazie

È stato utile?

Soluzione

Puoi fare qualsiasi ordine.Se la colonna non esiste, lascia semplicemente il tuo input enumerabile com'era prima.Per fare ciò, crea un selettore di chiave che restituisca lo stesso valore per tutti gli elementi.

Vedi esempio:

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();
    }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top