linq - IOrderedEnumerable 和防御性编程

标签 linq defensive-programming 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 操作,所以我担心副作用。

还有意见/建议? 谢谢

最佳答案

您可以进行任何订购。如果列不存在,只需将输入保留为可枚举的,就像以前一样。为此,请创建为所有元素返回相同值的键选择器。

参见示例:

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();
    }
}

关于linq - IOrderedEnumerable 和防御性编程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1791950/

相关文章:

c# - 如何查看 lambda 表达式的 SQL 查询

具有非自动属性的 C# 匿名支持字段

c# - OrderBy Linq 的奇怪行为

linq - 返回 IOrderedEnumerable<T> 而不是 IEnumerable<T> 的方法是否有利?

c# - 使用 LINQ 从数据表的列中消除逗号 (,)

c# - LINQ(到对象),在同一个 IEnumerable 上运行多个查询?

c# - 针对恶意攻击的防御性编程

c# - 为什么 IOrderedEnumerable 不重新实现 .Contains() 以获得性能

c# - 在通用存储库中使用 IEnumerable<T> 和 IQueryable<T>

security - web应用攻击,必须有防御方法