IOrderedEnumerable 和防御性编程

发布于 2024-08-12 04:01:25 字数 758 浏览 4 评论 0原文

我喜欢防御性编程。 我讨厌抛出异常,但这不是我问题的主题。

我改编了 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操作,所以我担心副作用。

以及意见/建议? 谢谢

I'm fond of defensive programming.
I hate exception throwing, but this is not the subject of my question.

I adapted an extension to linQ to be able to perform an order by with a column name

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

With defensive programming, this method returns the given enumerable if the column name is not valid.

Now I need to perform a secondary sorting with ThenBy.
So I need that signature :

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

I need to return a IOrderedEnumerable.
My problem is to keep my defensive programming feature : I must return the given set is the column name is invalid.

Is there a clean way to do this ? All I'm thinking of are kind of tricks :

  • Use reflection to order by the first found property, which is risky because the property may not be sorting-allowed
  • Implement my own IOrderedEnumerable, which is risky too because I perform ordering on IQueryable or IList, then I perform other LinQ operations, so I fear side effects.

And advice / suggestion ?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我是男神闪亮亮 2024-08-19 04:01:25

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

参见示例:

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

You may do any ordering. If column doesn't exist, just leave your input enumerable as it was before. To do this, create key selector that returns the same value for all elements.

See example:

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();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文