我喜欢防御性编程。我讨厌例外投掷,但这不是我问题的主题。

我对Linq进行了调整,以便能够用列名执行订单

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

防御性编程, ,如果列名不有效,此方法将返回给定的枚举。

现在我需要执行 次要分类 和那时。所以我需要那个签名:

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

我需要返回一个iOrderedEnumerable。我的问题是保持我的防御性编程功能:我必须返回给定的集合是列名称无效。

有什么干净的方法可以做到吗?我所想的只是技巧:

  • 使用第一个发现的属性订购订购的反射,这是有风险的,因为该物业可能不允许排序
  • 实现自己的iOrderedEnumerable,这也是有风险的,因为我对Iquery或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();
    }
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top