.Net 6 — Warning Possible Null Referente Return — uma forma de implementação
Muitas vezes na atualização de seus projetos para novas versões do .NET para uso da versão do C#8, você pode perceber Warnings em seu projeto que até então não eram geradas.
Por exemplo:
Warning : Possible Null Reference Return
Exemplo de Codigo com Warning
public sealed class TestClass
{
public string Test(string teste)
{
return teste;
}
}
Uma solução simples porém é alterar o retorno da função para public string? Test()
O que define que a função acima pode possuir retorno nulo.
Quais outras forma de implementar a solução para a Warning ?
Muitas vezes enquanto desenvolvemos sentimos a necessidade sobre retornos diferentes na chamada de uma função, como por exemplo se a execução ocorreu com sucesso, se houve alguma mensagem no processamento que o interrompeu, ou ainda se houve alguma exception.
Quando implementamos um controller com uma chamada na camada de service, é mais notório a necessidade deste tipo de retorno ate para que seja possível o retorno do http satuscode corretamente.
Ainda voltamos para o conceito do Polimorfismo, que permite que classes abstratas consigam receber comportamentos através de classes concretas. Por exemplo, um dispositivo USB, podemos considerar que o USB seria uma classe abstrata enquanto os dispositivos (Pen Driver, Ipad, Câmeras, etc) seriam as classes concretas. Ou seja, o USB é uma especificação que pode ter várias implementações com características diferentes.
A implementacao
Desenvolvemos um classe intermediaria Result que pode ser criada a partir de 3 objetos diferentes.
public readonly struct Result<A>
{ private readonly A? _value;
private readonly Exception? _exception;
private readonly bool _success;
private readonly StringBuilder? _erros; public Result(A value)
{
_success = true;
_value = value;
_exception = null;
_erros = null;
}public Result(Exception e)
{
_success = false;
_value = default(A);
_exception = e;
_erros = null;
}public Result(StringBuilder stringBuilder)
{
_success = false;
_value = default(A);
_exception = default(Exception);
_erros = stringBuilder;
}public static implicit operator Result<A>(A value)
{
return new Result<A>(value);
}
E um método para teste
public R Match<R>(Func<A, R> Succ, Func<Exception, R> Fail, Func<StringBuilder, R> SbuilderFail)
{
if (_success)
return Succ(_value); if (_exception is not null)
return Fail(_exception); return SbuilderFail(_erros);
}
Reescrevendo o Método original
public Result<string> Test(string _test)
{
if (_test is null)
return new Result<string>(new StringBuilder("Campo Nulo");
return _test;
}
Com uma implementação mais simples, temos o tratamento de retorno de mensagem caso o campo seja nulo ou o retorno do valor
Retorno da Chamada
Para o retorno da chamada, basta utilizar o metodo Match, conforme o exemplo abaixo.
Para utilizar o metodo Match utilize a classe que deseja o retorno do mesmo, e assim vc pode programar o seu codigo para cada tipo de retorno;
var executadoComSucesso = metodo.Match<bool>(
dado => { return true; },
exp => {return false; },
erro => {return false}
);
ou ainda capturando o valor da execução
var valorExecutado = metodo.Match<string>(
dado => { return dado; },
exp => {return exp.Message; },
erro => {return erro.Tostring();}
);
Em ambas as chamadas quando o executado o Método Match, a classe result avalia a o retorno da execução e dispara o código das funções programadas, que pode ser um grande recurso para simplificação do seu código.
Obrigado por sua leitura! Te aguardo nos próximos.