# Operações com Doubles

> [`Tango.CommonOperations.DoubleOperations`](https://github.com/gabrielschade/Tango/blob/master/Tango/Tango/Operations/DoubleOperations.cs)

Esta classe *estática* contém métodos e propriedades com as operações comuns para trabalhar com valores do tipo `double`. Todos os membros retornam os `delegates` que realizam a operação descrita.

> **Atenção**
>
> Todas as classes de operações com valores númericos (`int`, `decimal` e `double`) possuem as mesmas propriedades e métodos, alterando apenas o tipo dos parâmetros envolvidos.

## Propriedades

| Nome      | Tipo                                  | Descrição                                                                                          |
| --------- | ------------------------------------- | -------------------------------------------------------------------------------------------------- |
| Add       | Func\<double, double, double>         | Retorna uma função para representar o operador +.                                                  |
| Subtract  | Func\<double, double, double>         | Retorna uma função para representar o operador -.                                                  |
| Multiply  | Func\<double, double, double>         | Retorna uma função para representar o operador \*.                                                 |
| Divide    | Func\<double, double, double>         | Retorna uma função para representar o operador /.                                                  |
| Add3      | Func\<double, double, double, double> | Retorna uma função para representar o operador + entre três valores (valor1 + valor2 + valor3).    |
| Subtract3 | Func\<double, double, double, double> | Retorna uma função para representar o operador - entre três valores (valor1 - valor2 - valor3).    |
| Multiply3 | Func\<double, double, double, double> | Retorna uma função para representar o operador \* entre três valores (valor1 \* valor2 \* valor3). |
| Divide3   | Func\<double, double, double, double> | Retorna uma função para representar o operador / entre três valores (valor1 / valor2 / valor3).    |

## Métodos

| Nome          | Parâmetros                              | Retorno                       | Descrição                                                                                                    |
| ------------- | --------------------------------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------ |
| AddWith       | doublevalue                             | Func\<double, double>         | Retorna uma função parcialmente aplicada à função retornada por Add com o parâmetro informado.               |
| SubtractWith  | double value                            | Func\<double, double>         | Retorna uma função parcialmente aplicada à função retornada por Subtract com o parâmetro informado.          |
| MultiplyWith  | double value                            | Func\<double, double>         | Retorna uma função parcialmente aplicada à função retornada por Multiply com o parâmetro informado.          |
| DivideWith    | double value                            | Func\<double, double>         | Retorna uma função parcialmente aplicada à função retornada por Divide com o parâmetro informado.            |
| Add3With      | double value                            | Func\<double, double, double> | Retorna uma função parcialmente aplicada à função retornada por Add3 com o parâmetro informado.              |
| Add3With      | <p>double value</p><p>double value2</p> | Func\<double, double>         | Retorna uma função parcialmente aplicada à função retornada por Add3 com os dois parâmetros informados.      |
| Subtract3With | double value                            | Func\<double, double, double> | Retorna uma função parcialmente aplicada à função retornada por Subtract3 com o parâmetro informado.         |
| Subtract3With | <p>double value</p><p>double value2</p> | Func\<double, double>         | Retorna uma função parcialmente aplicada à função retornada por Subtract3 com os dois parâmetros informados. |
| Multiply3With | double value                            | Func\<double, double, double> | Retorna uma função parcialmente aplicada à função retornada por Multiply3 com o parâmetro informado.         |
| Multiply3With | <p>double value</p><p>double value2</p> | Func\<double, double>         | Retorna uma função parcialmente aplicada à função retornada por Multiply3 com os dois parâmetros informados. |
| Divide3With   | double value                            | Func\<double, double, double> | Retorna uma função parcialmente aplicada à função retornada por Divide3 com o parâmetro informado.           |
| Divide3With   | <p>double value</p><p>double value2</p> | Func\<double, double>         | Retorna uma função parcialmente aplicada à função retornada por Divide3 com os dois parâmetros informados.   |

## Como Usar

Como as propriedades retornam delegates para representar as operações, é possível utilizá-las como métodos.

&#x20;**Operação Add**

```csharp
double value = 10;
double value2 = 5;
double result = DoubleOperations.Add(value, value2);

//result= 15
```

&#x20;**Operação Subtract**

```csharp
double value = 10;
double value2 = 5;
double result = DoubleOperations.Subtract(value, value2);

//result= 5
```

&#x20;**Operação Multiply**

```csharp
double value = 10;
double value2 = 5;
double result = DoubleOperations.Multiply(value, value2);

//result= 50
```

&#x20;**Operação Divide**

```csharp
double value = 10;
double value2 = 5;
double result = DoubleOperations.Divide(value, value2);

//result= 2
```

Para os métodos temos uma sintaxe um pouco diferente, isso porque é realizada uma aplicação parcial ao método retornado pela própriedade.

Por conta disso, precisamos executar o método com os primeiros parâmetros, para obtermos um novo método que espera os parâmetros restantes:

&#x20;**Operação AddWith**

```csharp
double value = 10;
double value2 = 5;
Func<double ,double> addWith= DoubleOperations.AddWith(value);
double result = addWith(value2);

//result= 15
```

Também podemos realizar a chamada de forma concatenada:

```csharp
double value = 10;
double value2 = 5;
double result = DoubleOperations.AddWith(value)(value2);

//result= 15
```

As operações *\~With* existem para as quatro operações descritas, todas elas seguem a mesma característica do exemplo anterior.

Os métodos *\~With* também são aplicáveis as funções que utilizam três parâmetros, nestes casos você pode utilizar a aplicação parcial com um ou dois parâmetros, de acordo com a necessidade.

&#x20;**Operação Add3With**

```csharp
double value = 10;
double value2 = 5;
double value3 = 5
Func<double, double, double> addWith2 = DoubleOperations.Add3With(value);
double result = addWith2(value2, value3);

//result= 20
```

Também podemos realizar a chamada de forma concatenada:

```csharp
double value = 10;
double value2 = 5;
double value3 = 5
double result = DoubleOperations.Add3With(value)(value2, value3);

//result= 20
```

E por fim, podemos informar os dois parâmetros na primeira sobrecarga, em qualquer um dos modos:

```csharp
double value = 10;
double value2 = 5;
double value3 = 5
Func<double, double> addWith= DoubleOperations.Add3With(value, value2);
double result = addWith(value3);

//result= 20
```

```csharp
double value = 10;
double value2 = 5;
double value3 = 5
double result = DoubleOperations.Add3With(value,value2)(value3);

//result= 20
```

Perceba que as versões *\~With* passam pelo processo de **aplicação parcial**, não de currying.
