Prädikatdelegierte in C #


256

Kannst du mir erklären:

  • Was ist ein Prädikatdelegierter?
  • Wo sollen wir Prädikate verwenden?
  • Gibt es Best Practices bei der Verwendung von Prädikaten?

Beschreibender Quellcode wird geschätzt.

Antworten:


319

Ein Prädikat ist eine Funktion, die trueoder zurückgibt false. Ein Prädikatdelegat ist eine Referenz auf ein Prädikat.

Ein Prädikatdelegat ist also im Grunde eine Referenz auf eine Funktion, die trueoder zurückgibt false. Prädikate sind sehr nützlich, um eine Liste von Werten zu filtern - hier ein Beispiel.

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

Wenn Sie jetzt C # 3 verwenden, können Sie ein Lambda verwenden, um das Prädikat sauberer darzustellen:

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: Sollte das in deinem ersten Code-Snippet yeild returnstattdessen sein? Oder wie funktioniert das, wie iteriert es über die gesamte Liste?
VoodooChild

5
@VoodooChild: Denken Sie daran , dass das Prädikat wird für jedes Element in der Reihenfolge aufgerufen werden wiederum . Dies greaterThanTwoist auch returnnicht yield returnder FindAllFall, da es die Methode ist, die die Sequenz für Sie verwaltet.
Andrew Hare

1
@AndrewHare, ist es möglich i > val, statt i > 2wo der valvom Benutzer eingegebene Wert zu haben .
Mourya

81

Ausgehend von Andrews Antwort in Bezug auf c # 2 und c # 3 ... können Sie sie auch inline für eine einmalige Suchfunktion ausführen (siehe unten).

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

Hoffe das hilft.


11

Nur ein Delegat, der einen Booleschen Wert zurückgibt. Es wird häufig zum Filtern von Listen verwendet, kann aber überall verwendet werden.

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

9

Es gibt einen guten Artikel über Prädikate hier , obwohl es von der .NET2 Ära ist, so gibt es keine Erwähnung von Lambda - Ausdrücke in dort.


Der Link in Ihrer Antwort verweist nicht mehr auf einen aktuellen Artikel
David Cram

@ David Cram: Danke, ich habe den Link aktualisiert, um die Wayback-Maschine zu verwenden, obwohl der Artikel heutzutage wirklich veraltet aussieht.
LukeH

6

Was ist Prädikatdelegierter?

1) Prädikat ist eine Funktion, die true oder false zurückgibt. Dieses Konzept wurde in das .net 2.0-Framework integriert. 2) Es wird mit dem Lambda-Ausdruck (=>) verwendet. Es wird ein generischer Typ als Argument verwendet. 3) Damit kann eine Prädikatfunktion definiert und als Parameter an eine andere Funktion übergeben werden. 4) Es ist ein Sonderfall von a Func, da nur ein einziger Parameter verwendet wird und immer ein Bool zurückgegeben wird.

Im C # -Namensraum:

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

Es ist im System-Namespace definiert.

Wo sollen wir Predicate Delegate verwenden?

Wir sollten Predicate Delegate in den folgenden Fällen verwenden:

1) Zum Suchen von Elementen in einer generischen Sammlung. z.B

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

2) Grundlegendes Beispiel, das den Code verkürzt und true oder false zurückgibt:

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

Rufen Sie jetzt das obige Prädikat auf:

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

3) Eine anonyme Methode kann auch einem Prädikat-Delegatentyp wie folgt zugewiesen werden:

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

Best Practices für Prädikate?

Verwenden Sie Func, Lambda-Ausdrücke und Delegaten anstelle von Prädikaten.


5

Mit den auf Prädikaten basierenden Suchmethoden kann ein Methodendelegierter oder ein Lambda-Ausdruck entscheiden, ob ein bestimmtes Element eine „Übereinstimmung“ ist. Ein Prädikat ist einfach ein Delegat, der ein Objekt akzeptiert und true oder false zurückgibt: public delegate bool Predicate (T-Objekt);

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

2

Wenn Sie sich in VB 9 (VS2008) befinden, kann ein Prädikat eine komplexe Funktion sein:

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

Oder Sie können Ihr Prädikat als Lambda schreiben, solange es nur ein Ausdruck ist:

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

0

Das Prädikat fällt in C # unter die Kategorie der generischen Delegaten. Dies wird mit einem Argument aufgerufen und gibt immer einen booleschen Typ zurück. Grundsätzlich wird das Prädikat verwendet, um die Bedingung zu testen - wahr / falsch. Viele Klassen unterstützen Prädikate als Argument. Zum Beispiel erwartet list.findall das Parameterprädikat. Hier ist ein Beispiel für das Prädikat.

Stellen Sie sich einen Funktionszeiger mit der Signatur vor -

bool delegate myDelegate (T-Übereinstimmung);

Hier ist das Beispiel

Node.cs

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

Hauptklasse -

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

0

Einfach -> sie liefern True / False-Werte basierend auf der Bedingung, die hauptsächlich für die Abfrage verwendet wird. Meistens mit Delegierten verwendet

Betrachten Sie ein Beispiel für eine 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));

enthält Namen und Alter. Sagen wir jetzt, wir wollen Namen unter der Bedingung finden, dass ich sie benutze.

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

versuchte es einfach zu halten!


Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.