Como um programador experiente, você precisa lidar com ocorrências NullReferenceException todos os dias. Certo? Eu defendo que este é um problema de design. Por favor, considere o código que segue:

public interface IEmployeeRepository
{
  Employee GeyById(string id);
}

class EmployeeRepository : IEmployeeRepository
{
  public Employee GetById(string id)
    => new DbContext().Find(id);
}

Qual deveria ser o resultado da execução de GetById? Uma instância de Employee, certo? Infelizmente, este não é o caso sempre. Se não há registro com o id especificado, o resutaldo seria null. Talvez você esteja conformado com isso. Eu não!

O fato é que o código não é totalmente claro sobre qual deveria ser o resultado esperado para a execução desse método. Como programador experiente, algumas vezes você vai verificar o resultado do método, mas as vezes não…

Minha proposta seria começar a usar um container indicando que, as vezes, o resultado seria “sem resultado”.

public interface IEmployeeRepository
{
  Option<Employee> GeyById(string id);
}

class EmployeeRepository : IEmployeeRepository
{
  public Option<Employee>; GeyById(string id)
    =>; new DbContext().Find(id);
}

Agora o código é bem mais claro. Não acha?

Sobre a implementação de Option

O tipo Option é apenas uma struct que provê algumas conversões implicitas e algumas operações funcionais básicas.

A coisa mais interessante sobre essa abordagem é que os programadores consumindo EmployeeRepository do exemplo anterior não teriam mais acesso direto a (possível) instância de employee. O único meio para ter acesso seria através do container.

public IActionResult Get(string id) => _repository.GetById(id)
  .Match<IActionResult>(
    some: employee => Ok(employee),
    none: () => NotFound()
  );

NullReferenceExcption se foi!

Legal, não acha? Option está disponível no meu github.

Este post tem 3 comentários

  1. Fabio Gemignani

    Muito interessante, Elemar! São pequenos cuidados assim que tornam nossas aplicações cada vez melhores!

  2. Lucas Lopes

    Muito interessante.

  3. Daniel Pinto

    Excelente post.

    Uma duvida, no caso onde o repositorio esta implementado com async/await sendo que retorna uma Task funcionaria igual?

    A implementacao seria algo como: public async Option<Task<List>> GetXpto() ?

    Abs,

Deixe uma resposta