Qu'est ce qu'un prédicat en c#? [dupliquer]

cette question a déjà une réponse ici:

  • Prédicate Delegates in C# 9 réponses

je suis très nouveau à utiliser des prédicats et je viens d'apprendre à écrire:

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

quel sera le retour du prédicat, et comment est-il utile lors de la programmation?

147
demandé sur BradleyDotNET 2009-11-10 21:52:34

4 réponses

Predicate<T> est une construction fonctionnelle fournissant un moyen commode de tester fondamentalement si quelque chose est vrai d'un objet T donné.

Par exemple, supposons que j'ai une classe:

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

disons que j'ai un List<Person> people et je veux savoir s'il y a Quelqu'un qui s'appelle Oscar dans la liste.

sans utilisant un Predicate<Person> (ou Linq, ou l'un de ces objets de fantaisie), I pourrait toujours accomplir ceci en faisant ce qui suit:

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

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

c'est bien, mais alors disons que je veux vérifier s'il y a une personne qui s'appelle"Ruth"? Ou une personne dont l'âge est de 17 ans?

en utilisant un Predicate<Person> , je peux trouver ces choses en utilisant beaucoup moins de code:

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

Avis je l'ai dit beaucoup moins de code , pas beaucoup plus vite . Une idée fausse commune les développeurs ont est-ce que si quelque chose prend une ligne, il doit fonctionner mieux que quelque chose qui prend dix lignes. Mais dans les coulisses, la méthode Find , qui prend un Predicate<T> , ne fait qu'énumérer après tout. Le même est vrai pour beaucoup de Linq fonctionnalité.

alors regardons le code spécifique dans votre question:

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

ici nous avons un Predicate<int> pre qui prend un int a et retourne a % 2 == 0 . Il s'agit essentiellement d' test pour un nombre pair. Cela signifie:

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

et ainsi de suite. Cela signifie aussi, si vous avez un List<int> ints et que vous voulez trouver le premier nombre pair, vous pouvez simplement faire ceci:

int firstEven = ints.Find(pre);

bien sûr, comme pour tout autre type que vous pouvez utiliser dans le code, c'est une bonne idée de donner à vos variables des noms descriptifs; donc je conseillerais de changer le pre ci-dessus en quelque chose comme evenFinder ou isEven -- quelque chose le long de ces lignes. Alors le code ci-dessus est beaucoup plus clair:

int firstEven = ints.Find(evenFinder);
413
répondu Dan Tao 2009-11-10 19:24:04

le prédicat retournera toujours un booléen, par définition.

Predicate<T> est essentiellement identique à Func<T,bool> .

Les prédicats

sont très utiles dans la programmation. Ils sont souvent utilisés pour vous permettre de logique au moment de l'exécution, qui peut être aussi simple ou aussi compliqué que nécessaire.

par exemple, WPF utilise un Predicate<T> comme entrée pour le filtrage D'ICollectionView de ListView. Ce permet d'écrire une logique qui peut renvoyer un booléen déterminant si un élément spécifique doit être inclus dans la vue finale. La logique peut être très simple (il suffit de retourner un booléen sur l'objet) ou très complexe, tout à vous.

40
répondu Reed Copsey 2009-11-10 18:54:00

le code suivant peut vous aider à comprendre une certaine utilisation réelle des prédicats (combinés avec des itérateurs nommés).

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;
        }
    }
}
14
répondu Brahim Boulkriat 2013-11-03 11:51:56

En C# Prédicats sont tout simplement les délégués que le retour des booléens. Ils sont utiles (d'après mon expérience) lorsque vous cherchez dans une collection d'objets et que vous voulez quelque chose de précis.

je les ai récemment rencontrés en utilisant des commandes web de tiers (comme treeviews) donc quand j'ai besoin de trouver un noeud dans un arbre, j'utilise le .Méthode Find() et passer un prédicat qui sera de retour le nœud spécifique, je suis à la recherche pour. Dans votre exemple, si a mod 2 est 0, le délégué renvoie la valeur true. Je vous l'accorde, quand je cherche un noeud dans une arboreview, je compare ses propriétés nom, texte et valeur pour une correspondance. Lorsque le délégué trouve une correspondance, il renvoie le nœud spécifique que je cherchais.

12
répondu osij2is 2009-11-10 19:00:07