Prédicats délégués en C #

256

Pouvez vous m'expliquer:

  • Qu'est-ce qu'un délégué prédicat?
  • Où devrions-nous utiliser des prédicats?
  • Des meilleures pratiques lors de l'utilisation de prédicats?

Un code source descriptif sera apprécié.

Canavar
la source

Réponses:

319

Un prédicat est une fonction qui renvoie trueou false. Un délégué de prédicat est une référence à un prédicat.

Donc, fondamentalement, un délégué prédicat est une référence à une fonction qui retourne trueou false. Les prédicats sont très utiles pour filtrer une liste de valeurs - voici un exemple.

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list = new List<int> { 1, 2, 3 };

        Predicate<int> predicate = new Predicate<int>(greaterThanTwo);

        List<int> newList = list.FindAll(predicate);
    }

    static bool greaterThanTwo(int arg)
    {
        return arg > 2;
    }
}

Maintenant, si vous utilisez C # 3, vous pouvez utiliser un lambda pour représenter le prédicat d'une manière plus propre:

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list = new List<int> { 1, 2, 3 };

        List<int> newList = list.FindAll(i => i > 2);
    }
}
Andrew Hare
la source
@Andrew Hare: dans votre premier extrait de code, cela devrait-il être à la yeild returnplace? Ou comment ça marche, comment ça se répète sur toute la liste?
VoodooChild
5
@VoodooChild: N'oubliez pas que le prédicat sera appelé tour à tour pour chaque élément de la séquence . Ce greaterThanTwon'est returnpas le cas yield returnpuisque c'est la FindAllméthode qui gère la séquence pour vous.
Andrew Hare
1
@AndrewHare, est-il possible d'avoir i > val, au lieu de i > 2, où valest la valeur entrée par l'utilisateur.
Mourya
81

S'inspirant de la réponse d'Andrew en ce qui concerne c # 2 et c # 3 ... vous pouvez également les faire en ligne pour une fonction de recherche unique (voir ci-dessous).

using System;
using System.Collections.Generic;

class Program
{
    static void Main()
    {
        List<int> list = new List<int> { 1, 2, 3 };

        List<int> newList = list.FindAll(delegate(int arg)
                           {
                               return arg> 2;
                           });
    }
}

J'espère que cela t'aides.

WestDiscGolf
la source
11

Juste un délégué qui retourne un booléen. Il est beaucoup utilisé dans les listes de filtrage mais peut être utilisé où vous le souhaitez.

List<DateRangeClass>  myList = new List<DateRangeClass<GetSomeDateRangeArrayToPopulate);
myList.FindAll(x => (x.StartTime <= minDateToReturn && x.EndTime >= maxDateToReturn):
Adam Carr
la source
9

Il y a un bon article sur les prédicats ici , bien qu'il soit de l'ère .NET2, donc il n'y a aucune mention d'expressions lambda là-dedans.

LukeH
la source
Le lien dans votre réponse ne renvoie plus à un article réel
David Cram
@David Cram: Merci, j'ai mis à jour le lien pour utiliser la Wayback Machine, bien que l'article soit vraiment daté de nos jours.
LukeH
6

Qu'est-ce que Predicate Delegate?

1) Le prédicat est une fonctionnalité qui renvoie vrai ou faux.Ce concept est venu dans le cadre .net 2.0. 2) Il est utilisé avec l'expression lambda (=>). Il prend le type générique comme argument. 3) Il permet de définir une fonction de prédicat et de la passer en paramètre à une autre fonction. 4) C'est un cas particulier de a Func, en ce qu'il ne prend qu'un seul paramètre et renvoie toujours un booléen.

Dans l'espace de noms C #:

namespace System
{   
    public delegate bool Predicate<in T>(T obj);
}

Il est défini dans l'espace de noms System.

Où devrions-nous utiliser Predicate Delegate?

Nous devons utiliser Predicate Delegate dans les cas suivants:

1) Pour rechercher des éléments dans une collection générique. par exemple

var employeeDetails = employees.Where(o=>o.employeeId == 1237).FirstOrDefault();

2) Exemple de base qui raccourcit le code et renvoie vrai ou faux:

Predicate<int> isValueOne = x => x == 1;

maintenant, appelez le prédicat ci-dessus:

Console.WriteLine(isValueOne.Invoke(1)); // -- returns true.

3) Une méthode anonyme peut également être affectée à un type de délégué prédicat comme ci-dessous:

Predicate<string> isUpper = delegate(string s) { return s.Equals(s.ToUpper());};
    bool result = isUpper("Hello Chap!!");

Des meilleures pratiques concernant les prédicats?

Utilisez Func, Lambda Expressions et Delegates au lieu de Predicates.

Gul Md Ershad
la source
5

Les méthodes de recherche basées sur les prédicats permettent à un délégué de méthode ou à une expression lambda de décider si un élément donné est une «correspondance». Un prédicat est simplement un délégué qui accepte un objet et renvoie vrai ou faux: public delegate bool Predicate (objet T);

   static void Main()
        {
            string[] names = { "Lukasz", "Darek", "Milosz" };
            string match1 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
            //or
            string match2 = Array.Find(names, delegate(string name) { return name.Contains("L"); });
            //or
            string match3 = Array.Find(names, x => x.Contains("L"));


            Console.WriteLine(match1 + " " + match2 + " " + match3);     // Lukasz Lukasz Lukasz
        }
        static bool ContainsL(string name) { return name.Contains("L"); }
lukaszk
la source
2

Si vous êtes dans VB 9 (VS2008), un prédicat peut être une fonction complexe:

Dim list As New List(Of Integer)(New Integer() {1, 2, 3})
Dim newList = list.FindAll(AddressOf GreaterThanTwo)
...
Function GreaterThanTwo(ByVal item As Integer) As Boolean
    'do some work'
    Return item > 2
End Function

Ou vous pouvez écrire votre prédicat en tant que lambda, tant qu'il ne s'agit que d'une seule expression:

Dim list As New List(Of Integer)(New Integer() {1, 2, 3})
Dim newList = list.FindAll(Function(item) item > 2)
danlash
la source
0

Le prédicat appartient à la catégorie des délégués génériques en C #. Ceci est appelé avec un argument et renvoie toujours le type booléen. Fondamentalement, le prédicat est utilisé pour tester la condition - vrai / faux. De nombreuses classes prennent en charge le prédicat comme argument. Par exemple, list.findall attend le prédicat de paramètre. Voici un exemple du prédicat.

Imaginez un pointeur de fonction avec la signature -

délégué booléen myDelegate (correspondance T);

Voici l'exemple

Node.cs

namespace PredicateExample
{
    class Node
    {
        public string Ip_Address { get; set; }
        public string Node_Name { get; set; }
        public uint Node_Area { get; set; }
    }
}

Classe principale -

using System;
using System.Threading;
using System.Collections.Generic;

namespace PredicateExample
{
    class Program
    {
        static void Main(string[] args)
        {
            Predicate<Node> backboneArea = Node =>  Node.Node_Area == 0 ;
            List<Node> Nodes = new List<Node>();
            Nodes.Add(new Node { Ip_Address = "1.1.1.1", Node_Area = 0, Node_Name = "Node1" });
            Nodes.Add(new Node { Ip_Address = "2.2.2.2", Node_Area = 1, Node_Name = "Node2" });
            Nodes.Add(new Node { Ip_Address = "3.3.3.3", Node_Area = 2, Node_Name = "Node3" });
            Nodes.Add(new Node { Ip_Address = "4.4.4.4", Node_Area = 0, Node_Name = "Node4" });
            Nodes.Add(new Node { Ip_Address = "5.5.5.5", Node_Area = 1, Node_Name = "Node5" });
            Nodes.Add(new Node { Ip_Address = "6.6.6.6", Node_Area = 0, Node_Name = "Node6" });
            Nodes.Add(new Node { Ip_Address = "7.7.7.7", Node_Area = 2, Node_Name = "Node7" });

            foreach( var item in Nodes.FindAll(backboneArea))
            {
                Console.WriteLine("Node Name " + item.Node_Name + " Node IP Address " + item.Ip_Address);
            }

            Console.ReadLine();
        }
    }
}
agile
la source
0

Simplement -> ils fournissent des valeurs Vrai / Faux en fonction de la condition principalement utilisée pour les requêtes. principalement utilisé avec les délégués

considérer un exemple de liste

List<Program> blabla= new List<Program>();
        blabla.Add(new Program("shubham", 1));
        blabla.Add(new Program("google", 3));
        blabla.Add(new Program("world",5));
        blabla.Add(new Program("hello", 5));
        blabla.Add(new Program("bye", 2));

contient des noms et des âges. Maintenant, disons que nous voulons trouver des noms à condition donc je vais utiliser,

    Predicate<Program> test = delegate (Program p) { return p.age > 3; };
        List<Program> matches = blabla.FindAll(test);
        Action<Program> print = Console.WriteLine;
        matches.ForEach(print);

essayé de garder les choses simples!

Shubham Khare
la source