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

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

O delegate Func representa uma referência para um método e que pode possuir zero ou mais parâmetros sendo o último considerado como um parâmetro de retorno obrigatório. Func utiliza generics.

Para utilizar um Func, precisamos declarar um tipo de delegate com parametros e tipo de retorno com posterior atribuição de uma método que atenda ao que foi declarado.

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

Com Func podemos criar métodos anônimos e utilizar o tipo delegate ou expressão lambda .

Para utilizar Func precisamos adicionar o namespace System.

Um tipo de dado Func é declarado de acordo com a sintaxe 1 abaixo que utiliza a palavra reservada Func. Na segunda sintaxe, mostra a atribuição e instanciação de uma Func.

Sintaxe 1
public delegate TResult Func<in T, out TResult>(T arg);
Sintaxe 2
Func<TResult> nome_func = nome_metodo;
Func<TResult> nome_func = new Func<TResult>(nome_metodo);
Func<TResult> nome_func = new Func(nome_metodo);
Onde
TResult: Tipo de retorno 
T: tipo de dado
arg: argumento
Exemplo 1
using System;

public class Program
{
    public static int Teste() //static Main
    {
        return 555;//omitido
    }
    
    public static void Main(string[] args)
    {
        //Atribuição de método
        Func<int> mFunc = Teste;
        mFunc = new Func<int>(Teste);
    }
}
Saída
-

Como Func é uma referência para um método, esse possue as mesma características em relação ao uso parâmetros como mencionando acima. 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 void Func<T1,T2,...,T16>(T1 obj1, T2 obj, TN objN)
Exemplo 2
using System;
public class Program
{
    public static int Teste(string msg) //static Main
    {
        Console.WriteLine(msg);
        return msg.Length;
    }
    
    public static void Main(string[] args)
    {
        Func<string,int> mFunc = Teste;
        Console.WriteLine(mFunc("Func em C#"));
    }
}
Saída
Func em C#
10

Assim como os outros delegates estudados, uma Func pode ser utilizada como parâmetro de um método. Abaixo, a sintaxe que mostra o que foi discutido:

Sintaxe
modificador_acesso tipo_retorno nome_metodo(Func<T1,TN,TResult> nome_parametro);
Exemplo 3
using System;
public class Program
{
    public static int Print(string msg) //static Main
    {
        Console.WriteLine(msg);
        return msg.Length;
    }
    public static void Metodo(Func<string,int> Print, string msg)// static Main
    {
        Console.WriteLine(Print(msg));
    }
    public static void Main(string[] args)
    {
        Func<string,int> mFunc = Print;
        Metodo(Print,"Func em C#");
    }
}
Saída
Func em C#
10

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

Sintaxe
Func<T1,TN,TResult> nome_func = delegate(lista_parametros) 
{ 
   //corpo
};
Exemplo 4
using System;
public class Program
{
    public static void Main(string[] args)
    {
        Func<string,int> mFunc = delegate(string msg) //static Main
        {
            Console.WriteLine(msg);
            return msg.Length;
        };
        Console.WriteLine(mFunc("Func em C#"));
    }
}
Saída
Func em C#
10

Com Func podemos criar 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)
    {
        Func<int,int> mFunc = (num) => num%2 == 0;
        Console.WriteLine(mFunc(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 também podem ser utilizados 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
modificador_acesso tipo_retorno nome_metodo(Func<T1,TN,TResult> nome_parametro)
{
    //corpo
}
Sintaxe 2
nome_metodo(objeto_Func, lista_parametros);
Exemplo 6
using System;

public class Program
{
    public static int Metodo(Func<string,int> Print, string msg)// static Main
    {
        return Print(msg);
    }
    public static void Main()
    {
        int ret = Metodo((msg) => {
            Console.WriteLine(msg); 
            return msg.Length;
        },
        "metodo anonimo como parametro via lambda");
        
        ret = Metodo(delegate(string p)
        {  
            Console.WriteLine(p);
            return p.Length;
        }, "metodo anonimo como parametro");
    }
}
Saída
metodo anonimo como parametro via lambda
metodo anonimo como parametro

Assim como Predicate e Action, podemos utilizar o delegate Action para declaração de arrays. 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 Funct<T1,TResult>[] nome_array; //atributo
Funct<T1,TResult>[] nome_array[]; 
Sintaxe: Atribuição
Funct<T1,TResult>[] 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
{
    //static Main
    public static int Metodo1(string msg){ Console.WriteLine(msg); return msg.Length; }
    public static int Metodo2(string msg){ Console.WriteLine(msg); return msg.Length; }
    public static int Metodo3(string msg){ Console.WriteLine(msg); return msg.Length; }

	public static void Main()
	{
        Func<string,int>[] vetorFunc = { Metodo1, Metodo2, Metodo3};
        vetorFunc[0]("array de");
        vetorFunc[1]("func na ");
        vetorFunc[2]("linguagm c#");
	}
}
Saída
array de
func na
linguagem C#
  1. 11/10/2024 - revisão 1 - Correção: Sintaxes, Ex. 1/2; Ajustes pontuais
  2. 25/03/2024 - versão inicial