2009-02-17 20 views
240

¿Puede explicarme algo?Delegados de predicados en C#

  • ¿Qué es un Delegado Predicado?
  • ¿Dónde debemos usar los predicados?
  • ¿Alguna de las mejores prácticas al usar predicados?

código fuente descriptiva se apreciará

Gracias por todas las respuestas!

Respuesta

305

Un predicado es una función que devuelve true o false. Un delegado predicado es una referencia a un predicado.

Así que básicamente un delegado de predicado es una referencia a una función que devuelve true o false. Los predicados son muy útiles para filtrar una lista de valores; aquí hay un ejemplo.

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

Ahora bien, si usted está usando C# 3 se puede utilizar una lambda para representar el predicado de una manera más limpia:

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: en su primer fragmento de código, ¿debería ser 'yeild return' en su lugar? O cómo funciona eso, ¿cómo se repite en toda la lista? – VoodooChild

+4

@VoodooChild: Recuerde que se llamará el predicado para cada elemento en la secuencia * a su vez *. Entonces 'greaterThanTwo' tiene' return' no 'yield return' ya que es el método' FindAll' el que maneja la secuencia por usted. –

+0

@AndrewHare, ¿es posible tener 'i> val', en lugar de' i> 2', donde 'val' es el valor ingresado por el usuario. – Mourya

9

Solo un delegado que devuelve un valor booleano. Se usa mucho en las listas de filtrado, pero se puede usar en cualquier lugar que desee.

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

Hay un buen artículo sobre predicados here, aunque es de la época .NET2 , así que no hay mención de expresiones lambda allí.

+0

El enlace en su respuesta ya no enlaza a un artículo real –

+0

@David Cram: Gracias, he actualizado el enlace para usar Wayback Machine, aunque el artículo parece _realmente_ fechado hoy en día. – LukeH

79

Partiendo de la respuesta de Andrew con respecto a C# 2 y C# 3 ... también puede hacerlos en línea para una función de búsqueda única (ver a continuación).

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

Espero que esto ayude.

2

Si estás en VB 9 (VS2008), un predicado puede ser una función compleja:

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 

O usted puede escribir su predicado como lambda, siempre y cuando sea una sola expresión:

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

Los métodos de búsqueda basados ​​en predicados permiten un delegado método o expresión lambda para decidir si un elemento dado es un un predicado es simplemente un delegado aceptar un objeto y devolver verdadero o falso “partido”.: bool delegado pública Predicado (objeto 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"); } 
3

¿Qué es Predicate Delegate?

1) Predicado es una función que devuelve verdadero o falso. Este concepto ha venido en .NET 2.0 framework. 2) Se está utilizando con la expresión lambda (=>). Toma el tipo genérico como argumento. 3) Permite definir una función de predicado y pasarla como parámetro a otra función. 4) Es un caso especial de Func, en el sentido de que solo requiere un único parámetro y siempre devuelve un bool.

En C# espacio de nombres:

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

se define en el espacio de nombres System.

¿Dónde debemos usar Predicate Delegate?

Debemos utilizar predicado Delegado en los siguientes casos:

1) Para buscar elementos en una colección genérica. p.

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

2) Ejemplo básico que acorta el código y devuelve verdadero o falso:

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

ahora, la llamada arriba predicado:

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

3) Un método anónimo también puede asignarse a un tipo de delegado Predicado de la siguiente manera:

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

¿Alguna de las mejores prácticas sobre predicados?

Utilice Func, Lambda Expressions and Delegates en lugar de Predicates.