example - ¿Cuál es un predicado en c#?
summary example c# (4)
El predicado siempre devolverá un valor booleano, por definición.
Predicate<T>
es básicamente idéntico a Func<T,bool>
.
Los predicados son muy útiles en la programación. A menudo se utilizan para permitirle proporcionar lógica en tiempo de ejecución, que puede ser tan simple o tan complicado como sea necesario.
Por ejemplo, WPF usa un Predicate<T>
como entrada para el filtrado de un ICollectionView de ListView. Esto le permite escribir lógica que puede devolver un booleano que determina si un elemento específico debe incluirse en la vista final. La lógica puede ser muy simple (simplemente devuelve un booleano en el objeto) o muy compleja, todo depende de ti.
Esta pregunta ya tiene una respuesta aquí:
- Delegados de predicados en C # 9 respuestas
Soy muy nuevo en el uso de predicados y acabo de aprender a escribir:
Predicate<int> pre = delegate(int a){ a %2 == 0 };
¿Qué devolverá el predicado y cómo es útil cuando se programa?
El siguiente código puede ayudarlo a comprender algunos usos de predicados en el mundo real (combinados con iteradores con nombre).
namespace Predicate
{
class Person
{
public int Age { get; set; }
}
class Program
{
static void Main(string[] args)
{
foreach (Person person in OlderThan(18))
{
Console.WriteLine(person.Age);
}
}
static IEnumerable<Person> OlderThan(int age)
{
Predicate<Person> isOld = x => x.Age > age;
Person[] persons = { new Person { Age = 10 }, new Person { Age = 20 }, new Person { Age = 19 } };
foreach (Person person in persons)
if (isOld(person)) yield return person;
}
}
}
En C # Los predicados son simplemente delegados que devuelven booleanos. Son útiles (en mi experiencia) cuando buscas en una colección de objetos y quieres algo específico.
Me he topado con ellos recientemente al usar controles web de terceros (como treeviews), así que cuando necesito encontrar un nodo dentro de un árbol, uso el método .Find () y paso un predicado que devolverá el nodo específico que estoy buscando. En su ejemplo, si ''a'' mod 2 es 0, el delegado devolverá verdadero. Por supuesto, cuando estoy buscando un nodo en una vista de árbol, comparo sus propiedades de nombre, texto y valor para una coincidencia. Cuando el delegado encuentra una coincidencia, devuelve el nodo específico que estaba buscando.
Predicate<T>
es una construcción funcional que proporciona una forma conveniente de probar básicamente si algo es cierto para un objeto T
dado.
Por ejemplo, supongamos que tengo una clase:
class Person {
public string Name { get; set; }
public int Age { get; set; }
}
Ahora digamos que tengo personas de List<Person> people
y quiero saber si hay alguien llamado Oscar en la lista.
Sin usar un Predicate<Person>
(o Linq, o cualquiera de esas cosas elegantes), siempre podría lograr esto haciendo lo siguiente:
Person oscar = null;
foreach (Person person in people) {
if (person.Name == "Oscar") {
oscar = person;
break;
}
}
if (oscar != null) {
// Oscar exists!
}
Esto está bien, pero entonces digamos que quiero verificar si hay una persona llamada "Ruth". ¿O una persona cuya edad es 17?
Usando un Predicate<Person>
, puedo encontrar estas cosas usando MUCHO menos el código:
Predicate<Person> oscarFinder = (Person p) => { return p.Name == "Oscar"; };
Predicate<Person> ruthFinder = (Person p) => { return p.Name == "Ruth"; };
Predicate<Person> seventeenYearOldFinder = (Person p) => { return p.Age == 17; };
Person oscar = people.Find(oscarFinder);
Person ruth = people.Find(ruthFinder);
Person seventeenYearOld = people.Find(seventeenYearOldFinder);
Tenga en cuenta que dije mucho menos código , no mucho más rápido . Un error común que tienen los desarrolladores es que si algo toma una línea, debe funcionar mejor que algo que tome diez líneas. Pero detrás de las escenas, el método Find
, que toma un Predicate<T>
, simplemente está enumerando después de todo. Lo mismo es cierto para mucha de la funcionalidad de Linq.
Echemos un vistazo al código específico en su pregunta:
Predicate<int> pre = delegate(int a){ return a % 2 == 0; };
Aquí tenemos un Predicate<int> pre
que toma un int a
y devuelve a % 2 == 0
. Esto es esencialmente prueba para un número par. Lo que eso significa es:
pre(1) == false;
pre(2) == true;
Y así. Esto también significa que si tiene una List<int> ints
y desea encontrar el primer número par, puede hacer esto:
int firstEven = ints.Find(pre);
Por supuesto, como con cualquier otro tipo que pueda usar en el código, es una buena idea darle a sus variables nombres descriptivos; así que aconsejaría cambiar el precedente a algo como evenFinder
o isEven
, algo así. Entonces el código anterior es mucho más claro:
int firstEven = ints.Find(evenFinder);