Clique sobre os tópicos listados abaixo para navegar até o conteúdo desejado.

  1. Básico sobre Predicate
  2. Declaração de Predicate
  3. Predicate com parâmetros
  4. Predicate como parâmetro
  5. Método anônimo com Predicate
  6. Método anônimo como parâmetro
  7. Vetor de Predicate
  8. Retornando Predicate
  9. Limitações Predicate
  10. Predicate como atributo/propriedade de classe/struct

O tipo de dado delegate Predicate encapsula uma referência a um método podendo ter parâmetros e retorna apenas booleanos.

Esse delegate utiliza generics, pode conter até 16 parâmetros e utilizar o seu contrutor padrão para instanciar um objeto Predicate.

Com o delegate Predicate, podemos utilizar expressões lambda para declarar métodos anônimos e também ser usado como parâmetros de métodos.

Para utilizar Predicate precisamos adicionar o namespace System.

Para declarar um Predicate, nos baseamos na sintaxe 1 abaixo que utiliza a palavra reservada delegate. A sintaxe 2, mostra a atribuição e instanciação de um Predicate.

Sintaxe 1
modificador_acesso delegate bool Predicate()
Sintaxe 2
Predicate nome_predicate = nome_metodo;
Predicate nome_predicate = new Predicate(nome_metodo);
Exemplo 1
using System;
public class Program
{
    public static bool Metodo() //static Main
    {
        //omitido
    }
    public static void Main(string[] args)
    {
        //Atribuição de método
        Predicate meuPredicate = Metodo;
        meuPredicate = new meuPredicate();
    }
}
Saída
-

Como mencionado anteriormente, um delegate Predicate pode conter até 16 parâmetros utilizando generics. O uso das palavras reservadas ref e out, vistas nos conceitos de passagem por valor e referência em C# POO: Métodos, também podem ser utilizados.

Sintaxe 1
public delegate bool Predicate<T1,T2,...,T16>(T1 obj1, T2 obj, TN objN)
Sintaxe 2
Predicate<T1,T2,...,T16> nome_action = nome_metodo;
Predicate<T1,T2,...,T16> nome_action = new Predicate<T1,T2,...,T16>(nome_metodo);
Exemplo 2
using System;
public class Program
{
    public static bool Par(int numero) //static Main
    {
        return numero%2 == 0;
    }
    public static void Main(string[] args)
    {
        Predicate<int> meuPredicate = Par;
        Console.WriteLine(meuPredicate(2));
    }
}
Saída
True

Assim como Delegate, C# também permite que um Predicate seja utilizado como parâmetro de um método. Abaixo a sintaxe que mostra o que foi discutido:

Sintaxe 1
modificador_acesso tipo_retorno nome_metodo(tipo_predicate nome_parametro)
{
    //corpo
}
Exemplo 3
using System;
public class Program
{
    public static bool Par(int numero) //static Main
    {
        return numero%2 == 0;
    }
    public static bool Metodo(Predicate<int> Par, int numero)
    {
        return Par(numero);
    }
    public static void Main(string[] args)
    {
        Predicate<int> meuPredicate = Par;
        bool ret = Metodo(Par,2);
        Console.WriteLine(ret);
    }
}
Saída
True

Outra forma de utilizar Predicate é para a declaração de métodos anônimos. Esses, possuem as mesma características em relação ao uso parâmetros e o uso de ref e out.

Um método anônimo não possui nome, mas precisa utilizar a palavra reservada delegate como mostrado na sintaxe abaixo:

Sintaxe
Predicate<T1,T2,...,T16> = delegate(T1 obj1, T2 obj, TN objN) 
{ 
   //corpo
}
Exemplo 4
using System;
public class Program
{
    public static void Main(string[] args)
    {
        Predicate<int> meuPredicate = delegate(int numero)
        {
           return numero%2 == 0;
        };
        bool ret = meuPredicate(2);
        Console.WriteLine(ret);
    }
}
Saída
True

Com Predicate podemos declarar métodos anônimos utilizando expressão lambda como no exemplos abaixo mostrado.

Exemplo 5
using System;
public class Program
{
    public static void Main(string[] args)
    {
        Predicate<int> meuPredicate = (num) => num%2 == 0;
        Console.WriteLine(meuPredicate(2));
    }
}
Saída
True

É válido lembra que expressões lambda podem acessar variáveis e objetos em um escopo superior da qual foi declarada.

Os métodos anônimos utilizando Predicate também podem ser declarados como parâmetro de métodos. Abaixo a sintaxe que mostra a declaração de um método que recebe um método anônimo como argumento:

Sintaxe: Declaração
modificador_acesso tipo_retorno nome_metodo(tipo_predicate parametro_predicate, lista_parametros)
{
    //corpo
}
Sintaxe: Uso
nome_metodo(metodo_anonimo, lista_argumentos);
Exemplo 6
using System;
public class Program
{
    public static bool Metodo(Predicate<int> Par, int numero)
    {
        return Par(numero);
    }
    public static void Main(string[] args)
    {
        //lambda
        bool ret = Metodo(num => num%2 == 0,2);
        Console.WriteLine(ret);
        
        //delegate
        ret = Metodo( delegate(int num){
            return num%2 == 0;
        },2);
        Console.WriteLine(ret);
    }
}
Saída
metodo anonimo como parametro via lambda
metodo anonimo como parametro via delegate

Assim como outros tipos de dados, podemos também declarar array de Predicate. A atribuição de métodos aos elementos de um array é feita utilizando a posição/índice passado como argumento para o indexador [].

Sintaxe: Declaração
modificador_acesso Predicate<T1,TN>[] nome_array; //atributo
Predicate<T1,TN>[] nome_array[]; 
Sintaxe: Atribuição
Predicate<T1,TN>[] nome_array[] = { nome_metodo1, nome_metodo2, nome_metodoN }; //iniciado
nome_array[indice] = nome_metodo; //atribuição
Sintaxe: Uso
nome_array[indice](lista_argumentos)
Exemplo 7
using System;
public class Program
{
    public static bool Metodo1(int n){ return n%2 == 0; }
    public static bool Metodo2(int n){ return n%2 == 0; }
    public static bool Metodo3(int n){ return (n >= 0 && n <= 10); }

	public static void Main()
	{
        Predicate<int>[] array = { Metodo1, Metodo2, Metodo3 };
        Console.WriteLine(array[0](2));
        Console.WriteLine(array[1](3));
        Console.WriteLine(array[2](4));
	}
}
Saída
True
False
True
  1. 11/10/2024 - revisão 1 - Correção: Sintaxes, exemplo 7; Ajustes pontuais
  2. 22/03/2024 - versão inicial