سؤال

أنا مغرم بالبرمجة الدفاعية. أكره رمي الاستثناء ، لكن هذا ليس موضوع سؤالي.

لقد قمت بتكييف امتداد إلى 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();
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top