Option<T>

Tango.Types.Option<T>

Esta classe representa valores opcionais.

Instâncias de Option<T> encapsulam um valor que pode ou não existir. Este valor só pode ser acessado através dos métodos Match e Match2.

Os valores opcionais são considerados no estado de IsNone (não contendo nada) quando o valor armazenado nele é igual à null ou ao valor default de seu respectivo tipo.

Propriedades

Nome Tipo Descrição
IsSome bool Retorna true quando o valor contido no tipo opcional não é nulo nem igual ao seu valor default. Caso contrário retorna false.

Representa o estado "contendo alguma coisa".

IsNone bool Retorna true quando o valor contido no tipo opcional é nulo ou igual ao seu valor default. Caso contrário retorna false.

Representa o estado "não contendo nada".

Construtores

Parâmetros Retorno Descrição
T value Option<T> Inicializa uma nova instância de um valor opcional de acordo com o parâmetro recebido.

Métodos

Nome Parâmetros Retorno Descrição
Some T value Option<T> Inicializa uma nova instância de um valor opcional com o estado IsSome, caso o parâmetro recebido entre nas condições do estado IsNone é gerado um opcional neste estado.
None Option<T> Inicializa uma nova instância de um valor opcional com o estado IsNone.
Match

Func<T, TResult> methodWhenSome

Func<TResult> methodWhenNone

TResult Permite uma maneira de aplicar um método à um valor opcional sem necessidade de checar o estado do valor.

Para isso são passados dois métodos contendo o mesmo tipo de retorno por parâmetro, um que será chamado no caso do estado IsSome e outro que será chamado no caso do estado IsNone.

Match2

Option<T2> option2

Func<T, T2, TResult> methodWhenSome

Func<TResult> methodWhenNone

TResult Permite uma maneira de aplicar um método à dois valores opcionais sem necessidade de checar os estados de cada valor.

Para isso são passados dois métodos contendo o mesmo tipo de retorno por parâmetro, um que será chamado no caso dos dois valores opcionais estarem no estado IsSome e outro que será chamado caso algum dos valores esteja no estado IsNone.

Match

Action<T> actionWhenSome

Action actionWhenNone

void Permite uma maneira de aplicar um método à um valor opcional sem necessidade de checar o estado do valor.

Para isso são passados dois métodos que não retornam nada (void) por parâmetro, um que será chamado no caso do estado IsSome e outro que será chamado no caso do estado IsNone.

Match2

Option<T2> option2

Action<T, T2> actionWhenSome

Action actionWhenNone

void Permite uma maneira de aplicar um método à dois valores opcionais sem necessidade de checar os estados de cada valor.

Para isso são passados dois métodos que não retornam nada (void) por parâmetro, um que será chamado no caso dos dois valores opcionais estarem no estado IsSome e outro que será chamado caso algum dos valores esteja no estado IsNone.

Sobrecargas de operadores

Operador Parâmetros Descrição
Cast implícito

T value

Permite a realização de um cast implícito de qualquer valor T para seu respectivo valor opcional.

Internamente realiza a chamada do método Some.

Como Usar

Você pode criar um valor opcional de várias formas diferentes.

Criando valores opcionais

Você pode utilizar o construtor para criar valores contendo o estado IsSome ou IsNone de acordo com o parâmetro, conforme código:

Utilizando construtores

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

Você pode utilizar os métodos estáticos Some e None para especificar o estado desejado para o tipo opcional.

Neste caso deve-se tomar cuidado com a utilização do Some, pois caso o valor não atenda os requisitos, mesmo utilizando este método você irá gerar um valor com o estado IsNone.

Utilizando os métodos estáticos Some e None

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

Por último temos a versão mais simples de todas, através do cast implícito, com isso você não precisa se preocupar com nenhum tipo de sintaxe, basta criar o valor e a linguagem fará todo o trabalho.

Utilizando cast implícito

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

Através do cast implícito implementado no tipo Option, você poderá gerar novos métodos em sua aplicação sem alterar nada no corpo especial da função, apenas indicando que a função retorna um valor opcional.

Veja este exemplo:

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

Podemos reescrevê-lo de forma mais elegante:

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

E perceba que apenas sinalizamos que o retorno é um valor opcional. Nas instruções return estamos retornando uma string comum.

Neste método quando o valor informado for um número par, será retornado um valor opcional no estado IsSome contendo a string "Even", caso seja um valor impar, será criado um valor opcional com o estado IsNone, desta forma não será preciso tratar o valor nulo fora deste método.

Apesar deste método funcionar corretamente, é mais indicado utilizar o método None ao invés de null, conforme exemplo:

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

Obtendo informação de um valor opcional

Para obter os valores armazenados em um valor opcional é necessário utilizar os métodos Match ou Match2, não há nenhuma outra forma de obter os valores.

Com isso, o programar fica impossibilitado de obter o valor armazenado em um tipo opcional sem tratar adequadamente as duas possibilidades.

Os métodos Match esperam dois métodos por parâmetro, estes métodos podem realizar transformações no valor opcional, ou apenas retorná-los, conforme exemplos:

Utilizando Match com parâmetros nomeados

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

Perceba que o primeiro parâmetro é o método que será executado quando o estado for IsSome, por conta disso, este método recebe um parâmetro (number). No exemplo, o método apenas retorna este valor.

O segundo parâmetro é o método que será executado quando o estado for IsNone, ou seja, quando não haver valor no tipo opcional. Por conta disso, este segundo método não recebe nenhum parâmetro e precisa retornar um valor do mesmo, garantindo que o programa não irá gerar erros.

Você pode omitir os nomes dos parâmetros e utilizá-los normalmente como qualquer método C#:

Utilizando Match

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

Além disso, você também pode aplicar algum tipo de transformação no valor no momento de obtê-lo, como por exemplo, elevá-lo ao quadrado:

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

Você também pode retornar o valor que precisar para o caso do estado ser IsNone, nos exemplos anteriores foi utilizado o valor zero, mas não há nenhuma obrigatoriedade nisso.

Nos casos onde é necessário realizar uma comparação com dois valores opcionais de cada vez é necessário utilizar o método Match2, este método funciona de maneira similar aos exemplos anteriores, mas com dois valores opcionais ao invés de somente um.

Utilizando Match2

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

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

//value = 25

Neste exemplo está sendo realizada a soma de dois valores opcionais diferentes, no caso, ambos com o estado IsSome, fazendo com que o primeiro método seja executado:

(number1, number2) => number1 + number2

Neste método anônimo o parâmetro number1 contém o valor armazenado pela variável optinalValue (10) e o parâmetro number2 da variável optionalValue2(15).

Neste exemplo a variável value receberá o valor 25.

Caso um dos valores optionais estivesse no estado IsNone o segundo método seria disparado e o valor armazenado em value seria 2, conforme código a seguir.

Utilizando Match2

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

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

Tanto para o método Match quanto para o método Match2 há uma sobrecarga onde os métodos não precisam retornar nenhum tipo de valor (void).

O conceito dos valores opcionais pode ser encontrado na seção Conceitos > Valores Opcionais.

results matching ""

    No results matching ""