Delegados predicados en C #

256

Me puedes explicar:

  • ¿Qué es un delegado predicado?
  • ¿Dónde debemos usar predicados?
  • ¿Alguna mejor práctica al usar predicados?

Se apreciará el código fuente descriptivo.

Canavar
fuente

Respuestas:

319

Un predicado es una función que devuelve trueo false. Un delegado de predicado es una referencia a un predicado.

Entonces, básicamente, un predicado delegado es una referencia a una función que devuelve trueo 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, si está usando C # 3, puede usar 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);
    }
}
Andrew Hare
fuente
@ Andrew Hare: en tu primer fragmento de código, ¿debería ser yeild returneso? ¿O cómo funciona eso, cómo se repite en toda la lista?
VoodooChild
55
@VoodooChild: Recuerde que se llamará al predicado para cada elemento en la secuencia a su vez . No lo greaterThanTwoha returnhecho yield returnya que es el FindAllmétodo que maneja la secuencia por usted.
Andrew Hare
1
@AndrewHare, es posible tener i > val, en lugar de i > 2, dónde valestá el valor ingresado por el usuario.
Mourya
81

A partir de la respuesta de Andrew con respecto a c # 2 y c # 3 ... también puede hacerlas en línea para una función de búsqueda única (ver más abajo).

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.

WestDiscGolf
fuente
11

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

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

Hay un buen artículo sobre predicados aquí , aunque es de la época .NET2, así que no hay ninguna mención de las expresiones lambda en ese país.

LukeH
fuente
El enlace en su respuesta ya no enlaza con un artículo real
David Cram
@David Cram: Gracias, he actualizado el enlace para usar la máquina Wayback, aunque el artículo parece realmente anticuado hoy en día.
LukeH
6

¿Qué es el delegado predicado?

1) Predicate es una característica que devuelve verdadero o falso. Este concepto ha aparecido 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 predicada y pasarla como parámetro a otra función. 4) Es un caso especial de unFunc , ya que solo toma un único parámetro y siempre devuelve un bool.

En el espacio de nombres C #:

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

Se define en el espacio de nombres del sistema.

¿Dónde deberíamos usar Predicate Delegate?

Deberíamos usar Predicate Delegate en los siguientes casos:

1) Para buscar artículos en una colección genérica. p.ej

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, llame al predicado anterior:

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

3) También se puede asignar un método anónimo a un tipo de delegado de predicado como se muestra a continuación:

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

¿Alguna mejor práctica sobre predicados?

Use Func, Expresiones Lambda y Delegados en lugar de Predicados.

Gul Md Ershad
fuente
5

Los métodos de búsqueda basados ​​en predicados permiten que un delegado de métodos o una expresión lambda decida si un elemento dado es un "partido" Un predicado es simplemente un delegado que acepta un objeto y devuelve verdadero o falso: public delegate bool Predicate (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"); }
lukaszk
fuente
2

Si está 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 puede escribir su predicado como lambda, siempre y cuando sea solo una expresión:

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

Predicate cae en la categoría de delegados genéricos en C #. Esto se llama con un argumento y siempre devuelve el tipo booleano. Básicamente, el predicado se usa para probar la condición: verdadero / falso. Muchas clases admiten predicado como argumento. Por ejemplo, list.findall espera el predicado del parámetro. Aquí hay un ejemplo del predicado.

Imagine un puntero de función con la firma:

delegado bool myDelegate (coincidencia T);

Aquí está el ejemplo.

Node.cs

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

Clase principal -

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

Simplemente -> proporcionan valores verdaderos / falsos en función de la condición utilizada principalmente para las consultas. utilizado principalmente con delegados

considerar ejemplo de lista

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

contiene nombres y edades. Ahora digamos que queremos encontrar nombres en condición, así que usaré,

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

trató de mantenerlo simple!

Shubham Khare
fuente