> For the complete documentation index, see [llms.txt](https://gabriel-schade-cardoso.gitbook.io/tango-br/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://gabriel-schade-cardoso.gitbook.io/tango-br/conceitos/function-and-action.md).

# Delegates Func e Action

Um delegate é um tipo baseado em referência que por ser utilizado para encapsular um método, seja ele anônimo ou nomeado.

Esta é a forma que o C# utiliza para permitir que sejam criadas funções de alta ordem e para que seja possível tratar os métodos como membros de primeira ordem.

Existem diversos tipos de delegates já inclusos na linguagem, mas entre eles os dois mais importantes para a biblioteca **Tango** são: `Func` e o `Action`.

Os dois podem ser utilizados para representar qualquer método, com uma única, porém importante diferença.

O delegate `Func` só é capaz de encapsular métodos que geram resultados, ou seja, que possuem algum tipo de retorno.

Enquanto o delegate `Action` só é capaz de encapsular métodos que não geram resultados, ou seja, métodos do tipo `void`.

Existem uma série de sobrecargas para os dois delegates contendo diferentes números de *generics*. Estas sobrecargas são utilizadas para identificar os tipos dos parâmetros, que podem variar entre 0 e 16.

Veja um exemplo de encapsulamento de uma função de soma de dois inteiros através do delegate `Func`:

```csharp
Func<int,int,int> Add = (number1, number2) => number1 + number2;
```

Por conta das diferentes sobrecargas é possível utilizar diferentes combinações com o `Func` e o `Action`.

Neste próximo exemplo iremos encapsular um método para verificar se um numero inteiro é um número par:

```csharp
Func<int,bool> IsEven = number => number % 2 == 0;
```

Perceba que no delegate `Func` o último tipo informado no *generics* representa o tipo do retorno da função e os tipos anteriores são respectivamente o tipo de cada parâmetro.

O mesmo ocorre para o caso do Action, mas desta vez não temos um retorno.

```csharp
Action<double> WriteNumber = number => Console.WriteLine(number);
```

A própria biblioteca System.Linq abusa deste conceito, utilizando os delegates `Func` para tornar possível a passagem de expressões lambda como parâmetro para um método como o [`Select`](https://msdn.microsoft.com/en-us/library/bb548891%28v=vs.110%29.aspx), por exemplo.

A biblioteca **Tango** abusa deste conceito para criar funções de alta ordem que melhoram sua usabilidade, tornando o código mais limpo e expressivo.
