IOrderedEnumerable и защитное программирование
Я увлекаюсь защитным программированием. Я ненавижу бросать исключения, но это не предмет моего вопроса.
Я адаптировал расширение для linQ, чтобы иметь возможность выполнять заказ с именем столбца
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> list, string sortExpression)
При защитном программировании этот метод возвращает указанное перечисляемое значение, если имя столбца недопустимо.
Теперь мне нужно выполнить вторичную сортировку с помощью ThenBy. Так что мне нужна эта подпись:
public static IOrderedEnumerable<T> OrderBy<T>(this IEnumerable<T> list, string sortExpression)
Мне нужно вернуть IOrderedEnumerable. Моя проблема заключается в том, чтобы сохранить функцию защитного программирования: я должен вернуть заданный набор, если имя столбца неверно.
Есть ли чистый способ сделать это? Все, о чем я думаю, это своего рода хитрости:
- Использовать отражение для упорядочения по первому найденному свойству, что рискованно, поскольку свойство может быть не разрешено для сортировки
- Реализуйте свой собственный IOrderedEnumerable, что тоже рискованно, потому что я выполняю упорядочивание для IQueryable или IList, затем я выполняю другие операции LinQ, поэтому я боюсь побочных эффектов.
А совет / предложение? Спасибо
1 ответ
Вы можете сделать любой заказ. Если столбец не существует, просто оставьте свой ввод перечислимым, как это было раньше. Для этого создайте ключевой селектор, который возвращает одинаковое значение для всех элементов.
Смотрите пример:
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();
}
}