Proposta oficial de Type Unions para C#
(github.com/dotnet)Resumo
Documento que propõe type unions (ou discriminated unions) em C#.
Motivação
- No desenvolvimento de software, os valores armazenados em uma variável nem sempre são do mesmo tipo.
- Por exemplo, quando as definições de cliente e fornecedor compartilham apenas algumas propriedades, pode ser necessário realizar operações semelhantes para os dois tipos.
- Isso pode ser resolvido com herança, mas nem sempre é adequado para todas as situações.
- É necessário em C# um modo de armazenar em uma mesma variável um número limitado de tipos diferentes.
- Outras linguagens já oferecem esse recurso.
Solução
- A forma mais apropriada de implementar union types em C# pode ser pensada como uma hierarquia usando uma classe base abstrata.
- Porém, existem problemas como as limitações da hierarquia e a impossibilidade de representar unions de tipos não relacionados.
- Pode haver necessidade de vários tipos de unions, e esta proposta os classifica em quatro categorias.
Padrão - classe union
Declaração
- A classe union é declarada de forma semelhante a um enum.
- Cada membro pode ter variáveis de estado.
Criação
- É criada atribuindo uma instância do tipo de membro.
Desestruturação
- É desestruturada por meio de testes de tipo e pattern matching.
Exaustividade
- Se todos os tipos de membro forem considerados em uma expressão ou instrução
switch, não é necessário um caso padrão.
Nulabilidade
- É possível incluir
nullusando a notação padrão de nulabilidade.
Implementação
- A classe union é implementada como uma classe record abstrata.
Especialização - struct union
Declaração
- É declarada de forma semelhante à classe union, mas com a palavra-chave
structadicionada.
Criação
- É criada atribuindo uma instância do tipo de membro.
Desestruturação
- É desestruturada por meio de testes de tipo e pattern matching.
Exaustividade
- Se todos os tipos de membro forem considerados em uma expressão ou instrução
switch, não é necessário um caso padrão.
Nulabilidade
- É possível incluir
nullusando a notação padrão de nulabilidade.
Valor padrão
- A struct union pode ficar em um estado indefinido quando não recebe atribuição ou quando recebe o valor padrão.
Implementação
- A struct union é implementada como uma struct, e os tipos de membro são implementados como record structs aninhadas.
Temporário - union temporária
Sintaxe
- A union temporária é referenciada usando a sintaxe de padrão
or.
Nomeação
- É possível dar um nome comum a uma union temporária usando aliases de arquivo ou
usingglobal.
Criação
- É criada atribuindo uma instância do tipo de membro.
Desestruturação
- É desestruturada por meio de testes de tipo e pattern matching.
Exaustividade
- Se todos os tipos de membro forem considerados em uma expressão ou instrução
switch, não é necessário um caso padrão.
Nulabilidade
- É possível incluir
nullusando a notação padrão de nulabilidade.
Intercambialidade
- Unions temporárias com os mesmos tipos de membro são intercambiáveis.
Union definida pelo usuário
- É possível declarar tipos union que não podem ser definidos como classe union ou struct union.
- A hierarquia pode ser fechada usando o atributo
Closed. - Pode ser implementada como um wrapper struct usando o atributo
Union.
Unions comuns
Option
- É uma struct union que representa um valor que pode existir ou não.
Result
- É uma struct union que retorna um resultado bem-sucedido ou um erro em uma função.
Propostas relacionadas
Hierarquia fechada
- Declara um conjunto fechado de subtipos para um tipo base abstrato usando o atributo
Closed.
Valor singleton
- Tipos com um atributo singleton podem ser usados como valor em um contexto que não é de tipo.
Atalho para membro aninhado
- Permite fazer binding para membros estáticos ou tipos aninhados do tipo de destino usando nomes não vinculados.
Resumo do GN⁺
- Este documento propõe type unions em C#, oferecendo uma forma de armazenar vários tipos em variáveis em diferentes situações.
- É uma tentativa de trazer para C# um recurso que outras linguagens já oferecem.
- Pode ajudar desenvolvedores a melhorar a legibilidade e a manutenção do código.
- Um exemplo de outra linguagem com funcionalidade semelhante é F#.
1 comentários
Comentários do Hacker News
Já usei uniões discriminadas em F# e achei que C# também tivesse
O termo "união de tipos" me soa estranho
Como desenvolvedor C# de longa data, sinto que os casos de uso dessa proposta não estão claros
TypeScript tem uniões de tipos
Programar fica difícil sem uniões com pattern matching
Já tive experiência com field offsets em uniões em C#
u64e um objeto pode exigir um campo separado, desperdiçando 8 bytesUso construtores privados e um pacote nuget para que tipos switch não precisem de um caso
_Não foi mencionado como structs de união lidam com tearing sob modificação concorrente