OneOf para C# (.NET): guia completo com exemplos
A biblioteca OneOf é uma implementação de discriminated unions (uniões discriminadas) para a linguagem C#. Ela resolve um problema fundamental: como representar elegantemente, em uma linguagem com tipagem estática, um valor que pode ser um de vários tipos predefinidos. Em vez de usar object com conversão de tipos, Nullable ou criar hierarquias de classes, o OneOf oferece uma maneira type-safe e expressiva de trabalhar com esses valores.
Por que isso é necessário? Primeiro, melhora a legibilidade do código: a assinatura de um método que retorna OneOf<Success, Error> já indica claramente que a operação pode resultar em sucesso ou erro. Segundo, elimina toda uma classe de erros relacionados a conversões de tipo incorretas. Terceiro, o OneOf obriga o desenvolvedor a tratar todas as possibilidades, tornando o código mais robusto e previsível. Isso é especialmente útil em cenários onde tradicionalmente se usam exceções (para controle de fluxo) ou retorno de null.
O OneOf se encaixa perfeitamente no estilo de programação funcional em C#. Ele permite modelar o domínio com mais precisão: em vez de ter uma classe Result com flags e objetos aninhados, você pode usar OneOf<T0, T1, T2>, onde cada tipo representa um dos possíveis estados. Isso torna o código mais declarativo e reduz a quantidade de construções if-else.
Instalação
A instalação da biblioteca é feita através do NuGet Package Manager. Execute um dos seguintes comandos, dependendo da sua ferramenta:
# Package Manager Console
Install-Package OneOf
# .NET CLI
dotnet add package OneOf
# PackageReference (manualmente no .csproj)
<PackageReference Include="OneOf" Version="3.0.271" />
Após a instalação, adicione using OneOf; no início do seu arquivo.
Início rápido
Vamos ver um exemplo simples: uma função que divide um número por outro. Em vez de lançar uma exceção ao dividir por zero, retornaremos OneOf<double, string> — ou o resultado, ou uma mensagem de erro.
using OneOf;
public OneOf<double, string> SafeDivide(double a, double b)
{
if (b == 0)
return "Erro: divisão por zero";
return a / b;
}
// Uso
var result = SafeDivide(10, 2);
result.Switch(
value => Console.WriteLine($"Resultado: {value}"),
error => Console.WriteLine($"Erro: {error}")
);
// Saída: Resultado: 5
Observe: não usamos parâmetros out, não verificamos null e não capturamos exceções. Tudo o que precisamos é chamar Switch ou Match e fornecer manipuladores para cada caso possível.
Métodos e classes principais
A biblioteca oferece vários mecanismos-chave para trabalhar com uniões discriminadas. Vamos detalhar cada um deles.
1. OneOf<T0, T1, ...>
Assinatura: public class OneOf<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> : IOneOf
O que faz: Classe base que representa um valor que pode ser um dos tipos especificados. Suporta até 9 tipos. Conversão implícita de qualquer um dos tipos especificados para OneOf.
OneOf<int, string, bool> valor = 42; // conversão implícita
valor = "olá";
valor = true;
// Criação explícita
var valorExplicito = new OneOf<int, string>(100);
2. Switch
Assinatura: public void Switch(Action<T0> f0, Action<T1> f1, ...)
O que faz: Executa uma das ações fornecidas, dependendo de qual valor está armazenado no OneOf. Não retorna
Também na biblioteca
Monitoramento de aplicações em Rust: bibliotecas e ferramentas para rastreamento de desempenho
NestJS para TypeScript: guia completo com exemplos
Twig para PHP: guia completo do template engine
MPAndroidChart para Kotlin: guia completo com exemplos práticos
Registro para Kotlin: melhores soluções e bibliotecas