ИЗОБРАЖЕНИЕ ИЗОБРАЖЕНИЕ И ОБОСЛОВАНИЕ Программирование
-
22-09-2019 - |
Вопрос
Я люблю защитное программирование. Я ненавижу бросание исключений, но это не предмет моего вопроса.
Я адаптировал расширение в 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, поэтому я боюсь побочных эффектов.
И совет / предложение? Спасибо
Решение
Вы можете сделать любой заказ. Если столбец не существует, просто оставьте свой входной перечисление, как это было раньше. Для этого создайте селектор ключей, который возвращает одно и то же значение для всех элементов.
См. Пример:
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();
}
}