it-swarm.com.ru

Что такое предикат в c #?

Я очень новичок в использовании предикатов и только что научился писать:

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

Что вернет предикат и чем он полезен при программировании?

159
Jebli

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);
445
Dan Tao

Предикат всегда будет возвращать логическое значение по определению.

Predicate<T> в основном идентичен Func<T,bool>.

Предикаты очень полезны в программировании. Они часто используются для предоставления вам логики во время выполнения, которая может быть настолько простой или сложной, насколько это необходимо.

Например, WPF использует Predicate<T> в качестве входных данных для фильтрации объекта ListView ICollectionView. Это позволяет вам написать логику, которая может возвращать логическое значение, определяющее, должен ли определенный элемент быть включен в окончательное представление. Логика может быть очень простой (просто вернуть логическое значение для объекта) или очень сложной - все зависит от вас.

43
Reed Copsey

Следующий код может помочь вам понять использование предикатов в реальном мире (в сочетании с именованными итераторами).

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;
        }
    }
}
16
Brahim Boulkriat

В C # предикаты - это просто делегаты, которые возвращают логические значения. Они полезны (по моему опыту), когда вы просматриваете коллекцию объектов и хотите что-то конкретное.

Недавно я столкнулся с ними при использовании сторонних веб-элементов управления (например, древовидных представлений), поэтому, когда мне нужно найти узел в дереве, я использую метод .Find () и передаю предикат, который возвращает определенный узел, который я находясь в поиске. В вашем примере, если 'a' mod 2 равно 0, делегат вернет true. Конечно, когда я ищу узел в древовидной структуре, я сравниваю его имя, текст и свойства для соответствия. Когда делегат находит совпадение, он возвращает конкретный узел, который я искал.

14
osij2is