2009-02-17 11 views
240

Können Sie mir erklären;Prädikat Delegaten in C#

  • Was ist ein Predicate Delegate?
  • Wo sollten wir Prädikate verwenden?
  • Best Practices bei der Verwendung von Prädikaten?

Beschreibende Quellcode zu erkennen ist,

Danke für alle Antworten!

Antwort

305

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

Also im Grunde ist ein Prädikatdelegat eine Referenz auf eine Funktion, die true oder zurückgibt. Prädikate sind sehr nützlich, um eine Liste von Werten zu filtern - hier ist 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; 
    } 
} 

Nun, wenn Sie C# 3 verwenden, können Sie einen Lambda verwenden Sie das Prädikat in eine sauberere Art und Weise 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); 
    } 
} 
+0

@ Andrew Hare: in Dein erstes Code-Snippet, sollte das stattdessen "yeigd return" sein? Oder wie funktioniert das, wie durchläuft es die ganze Liste? – VoodooChild

+4

@VoodooChild: Denken Sie daran, dass das Prädikat für jedes Element in der Sequenz * wiederum * aufgerufen wird. Also hat 'größer als zwei' 'return' nicht' yield return', da es die 'FindAll' Methode ist, die die Sequenz für dich behandelt. –

+0

@AndrewHare, ist es möglich, "i> val" anstelle von "i> 2" zu haben, wobei "val" der vom Benutzer eingegebene Wert ist. – Mourya

9

Nur ein Delegat, das einen booleschen Wert zurückgibt. Es wird häufig in Filterlisten verwendet, kann aber überall verwendet werden.

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

Es gibt einen guten Artikel über Prädikate here, obwohl es von der .NET2 Ära , also gibt es dort keine Erwähnung von Lambda-Ausdrücken.

+0

Der Link in Ihrer Antwort führt nicht mehr zu einem aktuellen Artikel –

+0

@David Cram: Danke, ich habe den Link aktualisiert, um die Wayback Machine zu verwenden, obwohl der Artikel heutzutage _really_ datiert ist. – LukeH

79

Führt auf Andrew Antwort in Bezug auf C# 2 und C# 3 ... Sie können sie auch inline für eine einmalige Suchfunktion tun (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.

2

Wenn Sie in VB 9 (VS2008) 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, so lange schreiben, wie 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) 
4

das Prädikat basierte Suchverfahren ermöglichen eine Methode delegieren oder Lambda-Ausdruck, um zu entscheiden, ob ein bestimmtes Element A ein Prädikat ist einfach eine Delegierten ein Objekt und zurückkehren wahr oder falsch anzunehmen „entsprechen.“: public delegate bool Prädikat (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"); } 
3

Was ist Predicate Delegate?

1) Prädikat ist eine Funktion, die wahr oder falsch zurückgibt. Dieses Konzept ist in .net 2.0 Framework gekommen. 2) Es wird mit Lambda-Ausdruck (=>) verwendet. Es nimmt den generischen Typ als Argument an. 3) Es erlaubt eine Prädikatfunktion zu definieren und als Parameter an eine andere Funktion zu übergeben. 4) Es ist ein spezieller Fall von Func, in dem es nur einen einzigen Parameter braucht und immer einen bool zurückgibt.

In C# Namensraum:

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

Es wird definiert, im System-Namespace.

Wo sollten wir Predicate Delegate verwenden?

Wir sollen Prädikat Delegierten in folgenden Fällen:

1) Für Elemente in einer generischen Sammlung suchen. z.B.

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

2) Basic-Beispiel, das den Code und gibt wahr oder falsch verkürzt:

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

jetzt, Rufen oben Prädikat:

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

3) Eine anonyme Methode auch zugeordnet werden können zu einem Prädikat-Delegattyp wie folgt:

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

Best Practices zu Prädikaten?

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