2

私は防御的なプログラミングが好きです。私は例外スローが嫌いですが、これは私の質問の主題ではありません。

列名を使用して注文を実行できるように、linQの拡張機能を採用しました

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

防御プログラミングでは、列名が無効な場合、このメソッドは指定された列挙可能オブジェクトを返します。

次に、ThenByを使用して2次ソートを実行する必要があります。だから私はその署名が必要です:

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

IOrderedEnumerableを返す必要があります。私の問題は、防御的なプログラミング機能を維持することです。列名が無効である場合、指定されたセットを返す必要があります。

これを行うためのクリーンな方法はありますか?私が考えているのは一種のトリックです:

  • リフレクションを使用して、最初に見つかったプロパティで並べ替えます。これは、プロパティが並べ替えが許可されていない可能性があるため危険です。
  • 独自のIOrderedEnumerableを実装します。これは、IQueryableまたはIListで順序付けを実行し、次に他のLinQ操作を実行するため、リスクもあります。そのため、副作用が心配です。

そしてアドバイス/提案?ありがとう

4

1 に答える 1

3

あなたはどんな注文でもすることができます。列が存在しない場合は、入力を以前と同じように列挙可能のままにします。これを行うには、すべての要素に同じ値を返すキーセレクターを作成します。

例を参照してください:

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();
    }
}
于 2009-11-24T19:34:13.190 に答える