# Option\<T>

> [`Tango.Types.Option<T>`](https://github.com/gabrielschade/Tango/blob/master/Tango/Tango/Types/Option.cs)

This type represents an optional value.

Instances of `Option<T>` encapsulates the value as a container and only allow access through the `Match` e `Match2` methods.

Option values are considered in `IsNone` state when the encapsulated value are equals to `null` or equals to its default.

## Properties

| Name   | Type | Description                                                                                               |
| ------ | ---- | --------------------------------------------------------------------------------------------------------- |
| IsSome | bool | Returns true when the value is not null and is not equals to its default value. Otherwise, returns false. |
| IsNone | bool | Returns true when the value is null or equals to its default value. Otherwise, returns false.             |

## Constructors

| Parameters | Returns    | Description                             |
| ---------- | ---------- | --------------------------------------- |
| T value    | Option\<T> | Initialize a new instance of Option\<T> |

## Methods

| Name   | Parameters                                                                                                | Returns    | Description                                                                                                                                    |
| ------ | --------------------------------------------------------------------------------------------------------- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| Some   | T value                                                                                                   | Option\<T> | Creates Some\<T> if the parameter is not null or equals to its default value. Otherwise creates None.                                          |
| None   |                                                                                                           | Option\<T> | Creates Option\<T> with IsNone state.                                                                                                          |
| Match  | <p>Func\<T, TResult> methodWhenSome</p><p>Func\<TResult> methodWhenNone</p>                               | TResult    | This allows a sophisticated way to apply some method for Option\<T> values without having to check for the existence of a value.               |
| Match2 | <p>Option\<T2> option2</p><p>Func\<T, T2, TResult> methodWhenSome</p><p>Func\<TResult> methodWhenNone</p> | TResult    | This allows a sophisticated way to apply some method for two different Option\<T> values without having to check for the existence of a value. |
| Match  | <p>Action\<T> actionWhenSome</p><p>Action actionWhenNone</p>                                              | void       | This allows a sophisticated way to apply some method for Option\<T> values without having to check for the existence of a value.               |
| Match2 | <p>Option\<T2> option2</p><p>Action\<T, T2> actionWhenSome</p><p>Action actionWhenNone</p>                | void       | This allows a sophisticated way to apply some method for two different Option\<T> values without having to check for the existence of a value. |

## Operators Overload

| Operator      | Parameters | Description                                                                                           |
| ------------- | ---------- | ----------------------------------------------------------------------------------------------------- |
| Implicit Cast | T value    | Creates Some\<T> if the parameter is not null or equals to its default value. Otherwise creates None. |

## Usage

You can use an Option value in so many different ways.

### Creating an option value

You can use the constructor to create option values in `IsSome` or `IsNone` states, according its parameter.

&#x20;**Constructors**

```csharp
Option<int> valueWithSome = new Option<int>(10); //-> IsSome
Option<int> valueWithNone = new Option<int>(0);  //-> IsNone
```

You can also use the *static* methods `Some` or `None` to define the desired state of the value. The `Some` method can be little tricky because it there's no guarantees that the created value will be at `IsSome` state, because it depends on the value passed as parameter.

&#x20;**Some and None methods**

```csharp
Option<int> valueWithSome = Option<int>.Some(10); //-> IsSome
Option<int> valueWithNone = Option<int>.Some(0);  //-> IsNone
Option<int> value2WithNone = Option<int>.None();  //-> IsNone
```

Finally the simplest version: implict cast. Because of this feature you don't need to worry about any kind of syntax, you just create the value as regular types.

&#x20;**Implicit cast**

```csharp
Option<int> valueWithSome = 10; //-> IsSome
Option<int> valueWithNone = 0;  //-> IsNone
```

Through this implicit cast you can creates new option values by using regular return commands.

See:

```csharp
private Option<string> GetTextIfEven(int value)
{
  if (value % 2 == 0)
    return "Even";
  else
    return null;
}
```

In a more functional way:

```csharp
private Option<string> GetTextIfEven(int value)
  => value % 2 == 0 ? 
      "Even" 
      : null;
```

Realize the fact that the method returns just a regular `string` or `null` values, without creates an `Option` value.

This method works fine, but is more elegant to use the `None` method of `Option` class instead of `null`.

```csharp
private Option<string> GetTextIfEven(int value)
=> value % 2 == 0 ?
"Even"
: Option<string>.None();
```

### Getting value from an option

To get the value encapsulated by an `Option<T>` method is necessary uses `Match` or `Match2` methods. There aren't other way to get this value, so, you need to treat both cases properly.

The `Match` method receive two different functions as parameters, one for each case: `Some` and `None` state.

&#x20;**Match with named parameters**&#x20;

```csharp
Option<int> optionalValue = 10;
int value = optionalValue.Match(
        methodWhenSome: number => number,
        methodWhenNone: () => 0);
```

The first method is executed when the value `IsSome`, because of it, this method receive an `T` value as parameter (`int` in this example).

The second method is executed when the value `IsNone`, because of it, there's no parameter in this method.

These two functions are just regular parameters, so, you can omit the its names.

&#x20;**Match**

```csharp
Option<int> optionalValue = 10;
int value = optionalValue.Match(
        number => number,
        () => 0);
//value = 10
```

Besides that, you can also apply some transformation in value before got it, like square the value:

```csharp
Option<int> optionalValue = 10;
int value = optionalValue.Match(
        number => number * number,
        () => 0);
//value = 100
```

You can also returns any value in `IsNone` state, in the previous examples were used the zero value, but it isn't obrigatory.

Sometimes is necessary compare more than one `Option` values, this type provides the `Match2` method to compare two different values instead of just one.

&#x20;**Match2**&#x20;

```csharp
Option<int> optionalValue = 10;
Option<int> optionalValue2 = 15;

int value = optionalValue.Match2(
            optionalValue2,
            (number1, number2) => number1 + number2,
            () => 2);

//value = 25
```

In the previous sample a sum of two different `Option` value was made. In this particular case, both `Option` was in `IsSome` state, so the first method was executed:

`(number1, number2) => number1 + number2`

In this anonymous method the `number1` parameter received the value from `optinalValue` (10) and `number2` from `optionalValue2`(15), resulting 25.

The second method is executed when any `Option` value is in `IsNone` state.

&#x20;**Match2**

```csharp
Option<int> optionalValue = 10;
Option<int> optionalValue2 = Option<int>.None();

int value = optionalValue.Match2(
            optionalValue2,
            (number1, number2) => number1 + number2,
            () => 2);
// value = 2
```

There's an overload of `Match` and `Match2` methods to receive an `Action` as parameter instead of a `Func`.

The fundamentals about `Option values` can be find in [Fundamentals > Option Values](https://github.com/gabrielschade/tango/tree/379cc4a38ae47796971eb875ec66e7dc053a9081/Concepts/Optional%20Values.html) section.
