سؤال

هذا السؤال لديه بالفعل إجابة هنا:

أنا جديد جدا في استخدام المسندات والتعلم فقط كيفية الكتابة:

Predicate<int> pre = delegate(int a){ a %2 == 0 };

ماذا سيعود العودة، وكيف يكون مفيدا عند البرمجة؟

هل كانت مفيدة؟

المحلول

Predicate<T> هو بناء وظيفي يوفر وسيلة مريحة لاختبار أساسا إذا كان هناك شيء صحيح T هدف.

على سبيل المثال، لنفترض أن لدي فئة:

class Person {
    public string Name { get; set; }
    public int Age { get; set; }
}

الآن دعنا نقول أن لدي List<Person> people وأريد أن أعرف ما إذا كان هناك أي شخص يدعى أوسكار في القائمة.

بدون باستخدام أ Predicate<Person> (أو LINQ، أو أي من تلك الأشياء الفاخرة)، يمكنني دائما تحقيق ذلك من خلال القيام بما يلي:

Person oscar = null;
foreach (Person person in people) {
    if (person.Name == "Oscar") {
        oscar = person;
        break;
    }
}

if (oscar != null) {
    // Oscar exists!
}

هذا جيد، لكن دعنا نقول أنني أريد التحقق مما إذا كان هناك شخص يدعى "روث"؟ أو شخص عمره 17؟

باستخدام أ Predicate<Person>, ، يمكنني أن أجد هذه الأشياء باستخدام رمز أقل بكثير:

Predicate<Person> oscarFinder = (Person p) => { return p.Name == "Oscar"; };
Predicate<Person> ruthFinder = (Person p) => { return p.Name == "Ruth"; };
Predicate<Person> seventeenYearOldFinder = (Person p) => { return p.Age == 17; };

Person oscar = people.Find(oscarFinder);
Person ruth = people.Find(ruthFinder);
Person seventeenYearOld = people.Find(seventeenYearOldFinder);

إشعار قلت كثيرا أقل رمز, ، ليس كثيرا أسرع. وبعد تتمثل المطورون الخاطئ المشترك في أنه إذا كان هناك شيء ما يأخذ سطرا واحدا، يجب أن يؤدي ذلك بشكل أفضل من شيء يستغرق عشر خطوطا. ولكن وراء الكواليس، Find الطريقة، التي تأخذ Predicate<T>, ، تعداد فقط بعد كل شيء. وينطبق الشيء نفسه على الكثير من وظائف LINQ.

لذلك دعونا نلقي نظرة على التعليمات البرمجية المحددة في سؤالك:

Predicate<int> pre = delegate(int a){ return a % 2 == 0; };

هنا لدينا Predicate<int> pre التي تأخذ int a والعودة a % 2 == 0. وبعد هذا اختبار أساسا لعدد حتى. ماذا يعني ذلك:

pre(1) == false;
pre(2) == true;

وهلم جرا. هذا يعني أيضا، إذا كان لديك List<int> ints وتريد العثور على أول رقم حتى، يمكنك فقط القيام بذلك:

int firstEven = ints.Find(pre);

بالطبع، كما هو الحال مع أي نوع آخر يمكنك استخدامه في التعليمات البرمجية، من الجيد إعطاء الأسماء الوصفية للمتغيرات الخاصة بك؛ لذلك أود أن ننصح بتغيير ما سبق pre إلى شيء مثل evenFinder أو isEven - شيء على طول تلك الخطوط. ثم الرمز أعلاه هو الكثير أكثر وضوحا:

int firstEven = ints.Find(evenFinder);

نصائح أخرى

سيعود المسند دائما منطقي، بحكم التعريف.

Predicate<T> هو أساسا مماثلة ل Func<T,bool>.

المسندات مفيدة للغاية في البرمجة. غالبا ما تستخدم للسماح لك بتوفير المنطق في وقت التشغيل، والتي يمكن أن تكون بسيطة أو معقدة حسب الضرورة.

على سبيل المثال، يستخدم WPF Predicate<T> كمدخلات لتصفية iColletionView ListView. يتيح لك ذلك كتابة المنطق الذي يمكنه إرجاع أداة تحديد المنطقية ما إذا كان يجب تضمين عنصر محدد في الرأي النهائي. يمكن أن يكون المنطق بسيطا جدا (فقط إرجاع منطقي على الكائن) أو معقدة للغاية، كل ما يصل إليك.

يمكن أن يساعدك الكود التالي في فهم بعض الاستخدام العالمي الحقيقي للمسندات (جنبا إلى جنب مع ITERATONS المسمى).

namespace Predicate
{
    class Person
    {
        public int Age { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            foreach (Person person in OlderThan(18))
            {
                Console.WriteLine(person.Age);
            }
        }

        static IEnumerable<Person> OlderThan(int age)
        {
            Predicate<Person> isOld = x => x.Age > age;
            Person[] persons = { new Person { Age = 10 }, new Person { Age = 20 }, new Person { Age = 19 } };

            foreach (Person person in persons)
                if (isOld(person)) yield return person;
        }
    }
}

في C # يتداول ببساطة مفوضين الذين يعودون المنطمنون. إنها مفيدة (في تجربتي) عندما تبحث عن طريق مجموعة من الكائنات وأريد شيئا محددا.

لقد قمت مؤخرا بتشغيلها في استخدام عناصر تحكم Web Party 3 (مثل TreeViews) لذلك عندما أحتاج إلى العثور على عقدة داخل شجرة، فأنا أستخدم أسلوب .find () وتمرير المسند الذي سيعود العقدة المحددة البحث عن. في مثالك، إذا كان 'A' MOD 2 هو 0، سيعود المندوب صحيحا. منحت، عندما أبحث عن عقدة في TreeView، أقارن اسمها واسم النصوص والنص وقيمها للمباراة. عندما يجد المندوب مباراة، فإنه يعيد العقدة المحددة التي كنت أبحث عنها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top