Ir para o conteúdo do rodapé
AJUDA DO .NET

Uniões discriminadas em C# (Como funciona para desenvolvedores)

Como desenvolvedor .NET que trabalha com geração dinâmica de PDFs usando o IronPDF , você frequentemente precisa representar e gerenciar uma variedade de tipos específicos — pense em diferentes tipos de dados de documentos, mensagens de registro, funções de usuário ou opções de exportação. É aqui que entra em jogo o conceito de união discriminada em C#.

Embora o C# não tenha suporte nativo para uniões discriminadas da mesma forma que o F# ou o Rust, ainda é possível simular uniões discriminadas de forma eficaz. Neste artigo, vamos explorar como definir e usar um tipo de união discriminada em C#, demonstrar como aplicá-lo com o IronPDF para processamento de PDFs em situações reais e analisar os benefícios que esse padrão oferece, especialmente quando combinado com o casamento de padrões.

What Are Discriminated Unions in C#?

As uniões discriminadas, também conhecidas como uniões etiquetadas ou tipos de união, permitem que uma variável armazene um valor de um conjunto limitado de opções possíveis, onde cada opção está associada a um identificador de caso exclusivo.

Em outras linguagens, como F#, você pode defini-las usando a palavra-chave union. O C# não oferece esse recurso nativamente, mas os desenvolvedores podem usar combinações inteligentes de registros, classes e expressões switch para simulá-los.

Por exemplo:

public abstract record PdfAction;
public record GenerateReport(string ReportName) : PdfAction;
public record LogError(string Message) : PdfAction;
public record ExportToExcel(string FilePath) : PdfAction;
public abstract record PdfAction;
public record GenerateReport(string ReportName) : PdfAction;
public record LogError(string Message) : PdfAction;
public record ExportToExcel(string FilePath) : PdfAction;
Public MustOverride ReadOnly Property PdfAction() As record
public record GenerateReport(String ReportName) : PdfAction
public record LogError(String Message) : PdfAction
public record ExportToExcel(String FilePath) : PdfAction
$vbLabelText   $csharpLabel

Cada registro acima representa um caso individual da união. O tipo base PdfAction é o discriminante.

Por que as uniões discriminadas são importantes nos fluxos de trabalho do IronPDF

Imagine que você está criando um gerador de relatórios em PDF usando o IronPDF e precisa executar diferentes ações com base na entrada do usuário — talvez gerar um PDF, registrar um erro ou exportar dados.

O uso de uniões discriminadas em C# permite representar esses tipos de opção de forma clara, resultando em segurança em tempo de compilação, menos erros e uma lógica mais transparente.

Eis como você pode usá-lo com o IronPDF:

void HandlePdfAction(PdfAction action)
{
    switch (action)
    {
        case GenerateReport r:
            var pdf = new IronPdf.HtmlToPdf().RenderHtmlAsPdf("<h1>" + r.ReportName + "</h1>");
            pdf.SaveAs(r.ReportName + ".pdf");
            break;
        case LogError e:
            Console.WriteLine("Logging Error: " + e.Message);
            break;
        case ExportToExcel x:
            Console.WriteLine("Exporting to Excel at " + x.FilePath);
            break;
        default:
            throw new NotSupportedException("Unknown action");
    }
}
void HandlePdfAction(PdfAction action)
{
    switch (action)
    {
        case GenerateReport r:
            var pdf = new IronPdf.HtmlToPdf().RenderHtmlAsPdf("<h1>" + r.ReportName + "</h1>");
            pdf.SaveAs(r.ReportName + ".pdf");
            break;
        case LogError e:
            Console.WriteLine("Logging Error: " + e.Message);
            break;
        case ExportToExcel x:
            Console.WriteLine("Exporting to Excel at " + x.FilePath);
            break;
        default:
            throw new NotSupportedException("Unknown action");
    }
}
Private Sub HandlePdfAction(ByVal action As PdfAction)
	Select Case action
'INSTANT VB TODO TASK: The following 'case' pattern variable is not converted by Instant VB:
'ORIGINAL LINE: case GenerateReport r:
		Case GenerateReport r
			Dim pdf = (New IronPdf.HtmlToPdf()).RenderHtmlAsPdf("<h1>" & r.ReportName & "</h1>")
			pdf.SaveAs(r.ReportName & ".pdf")
'INSTANT VB TODO TASK: The following 'case' pattern variable is not converted by Instant VB:
'ORIGINAL LINE: case LogError e:
		Case LogError e
			Console.WriteLine("Logging Error: " & e.Message)
'INSTANT VB TODO TASK: The following 'case' pattern variable is not converted by Instant VB:
'ORIGINAL LINE: case ExportToExcel x:
		Case ExportToExcel x
			Console.WriteLine("Exporting to Excel at " & x.FilePath)
		Case Else
			Throw New NotSupportedException("Unknown action")
	End Select
End Sub
$vbLabelText   $csharpLabel

Essa abordagem mantém seu código organizado e robusto, além de facilitar a compreensão de todas as opções possíveis em um único local por parte dos desenvolvedores.

Simulating Discriminated Unions in C# – Struct vs. Record vs. Class

Embora o C# não possua a palavra-chave union, você pode simular uniões discriminadas usando:

  • Registros: Ideal para dados imutáveis ​​e oferece suporte à correspondência de padrões de forma clara.
  • Classes: Mais flexíveis com herança e semântica de referência.
  • Structs: Úteis para tipos de valor, mas menos flexíveis ao lidar com tipos de referência ou herança.

Uniões Discriminadas em C# (Como Funciona para Desenvolvedores): Figura 1 - Struct vs. Record vs. Class

Se o desempenho e o layout da memória forem importantes — por exemplo, em registro de PDFs de alto rendimento — você pode considerar usar uniões discriminadas de structs com cautela:

public interface IAction { }
public readonly struct SaveAction : IAction
{
    public string FileName { get; }
    public SaveAction(string fileName) => FileName = fileName;
}
public interface IAction { }
public readonly struct SaveAction : IAction
{
    public string FileName { get; }
    public SaveAction(string fileName) => FileName = fileName;
}
Public Interface IAction
End Interface
'INSTANT VB WARNING: VB has no equivalent to the C# readonly struct:
'ORIGINAL LINE: public readonly struct SaveAction : IAction
Public Structure SaveAction
	Implements IAction

	Public ReadOnly Property FileName() As String
	Public Sub New(ByVal fileName As String)
		Me.FileName = fileName
	End Sub
End Structure
$vbLabelText   $csharpLabel

Observação: você perderá algumas vantagens de correspondência de padrões com structs, especialmente ao depender de expressões switch.

Benefits of Using Discriminated Unions in C

Existem diversas vantagens importantes na adoção desse padrão de engenharia de software:

  • Segurança em tempo de compilação: Você detectará casos ausentes em uma expressão switch antes da execução do programa.
  • Lógica mais clara: É mais fácil escrever, comentar e raciocinar sobre ações com casos nomeados.
  • Separação de responsabilidades: Você desvincula comportamentos com base em dados , em vez de hierarquias de tipos.
  • Facilidade de refatoração: Adicionar ou remover casos torna-se mais simples.

Quando usado em conjunto com o IronPDF, isso facilita o gerenciamento da entrada do usuário, da lógica de renderização ou a criação de modelos dinâmicos com diferentes fluxos de valores.

Quando usar uniões discriminadas com o IronPDF

Aqui estão alguns cenários práticos onde esse padrão se destaca:

  • Fluxos de trabalho de geração de PDF: diferentes etapas no ciclo de vida de um documento (gerar, salvar, enviar por e-mail).
  • Modelos de permissão: Representam diferentes níveis de acesso do usuário.
  • Sistemas de registro: Utilize tipos de união discriminados para os níveis de registro (info, error, debug).
  • Testes unitários: Defina as ações de teste como tipos de união para árvores lógicas de fácil manutenção.
  • Opções de exportação: Representa destinos de saída como PDF, Excel e Word como instâncias de união.

Uniões Discriminadas em C# (Como Funciona para Desenvolvedores): Figura 2 - Cenários comuns para uniões discriminadas em aplicativos .NET

Exemplo – Manipulando ações de PDF a partir de eventos da interface do usuário

Suponhamos que você esteja capturando eventos da interface do usuário e queira encaminhá-los para tarefas do IronPDF usando uniões discriminadas:

public abstract record UserAction;
public record GeneratePdf(string HtmlContent, string FileName) : UserAction;
public record ShowMessage(string Text) : UserAction;
public record ExitApplication() : UserAction;
void OnUserEvent(UserAction action)
{
    switch (action)
    {
        case GeneratePdf pdf:
            var renderer = new IronPdf.HtmlToPdf();
            var document = renderer.RenderHtmlAsPdf(pdf.HtmlContent);
            document.SaveAs(pdf.FileName);
            break;
        case ShowMessage msg:
            MessageBox.Show(msg.Text);
            break;
        case ExitApplication:
            Application.Exit();
            break;
    }
}
public abstract record UserAction;
public record GeneratePdf(string HtmlContent, string FileName) : UserAction;
public record ShowMessage(string Text) : UserAction;
public record ExitApplication() : UserAction;
void OnUserEvent(UserAction action)
{
    switch (action)
    {
        case GeneratePdf pdf:
            var renderer = new IronPdf.HtmlToPdf();
            var document = renderer.RenderHtmlAsPdf(pdf.HtmlContent);
            document.SaveAs(pdf.FileName);
            break;
        case ShowMessage msg:
            MessageBox.Show(msg.Text);
            break;
        case ExitApplication:
            Application.Exit();
            break;
    }
}
Public MustOverride ReadOnly Property UserAction() As record
public record GeneratePdf(String HtmlContent, String FileName) : UserAction
public record ShowMessage(String Text) : UserAction
public record ExitApplication() : UserAction
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'void OnUserEvent(UserAction action)
'{
'	switch (action)
'	{
'		case GeneratePdf pdf:
'			var renderer = New IronPdf.HtmlToPdf();
'			var document = renderer.RenderHtmlAsPdf(pdf.HtmlContent);
'			document.SaveAs(pdf.FileName);
'			break;
'		case ShowMessage msg:
'			MessageBox.Show(msg.Text);
'			break;
'		case ExitApplication:
'			Application.@Exit();
'			break;
'	}
'}
$vbLabelText   $csharpLabel

Isso permite representar eventos com lógica clara e reduz a dependência de tipos de objetos públicos ou manipulação excessivamente dinâmica.

Future Outlook – Will C# Ever Support Native Discriminated Unions?

Já existe uma proposta para adicionar suporte nativo a uniões discriminadas em C#, especialmente devido à crescente demanda por sistemas de tipos mais expressivos. Embora a linguagem ainda não tenha introduzido uma palavra-chave union propriamente dita, o C# continua a evoluir, aproximando recursos como registros, correspondência de padrões e expressões switch da funcionalidade completa de união discriminada.

Os desenvolvedores .NET interessados ​​em construções de linguagem modernas e amigáveis ​​à programação funcional devem acompanhar de perto este espaço.

Considerações finais

O uso de uniões discriminadas em C#, mesmo sem suporte nativo, pode melhorar significativamente a forma como você estrutura e representa a lógica em aplicações IronPDF . Ao aproveitar registros, expressões switch e classes base, você tornará seu código mais legível, fácil de manter e resistente a erros, além de desbloquear uma maneira mais declarativa e expressiva de lidar com tarefas relacionadas a PDFs.

Se você é um engenheiro de software que desenvolve aplicações .NET modernas e flexíveis, esse padrão é indispensável em seu conjunto de ferramentas.

Experimente o IronPDF gratuitamente hoje mesmo!

Pronto para levar a geração de PDFs em C# para o próximo nível? Baixe o IronPDF e comece com um teste gratuito . Seja para gerar documentos a partir de HTML, registrar exportações ou automatizar relatórios usando uniões discriminadas, o IronPDF oferece o poder e o desempenho que o seu aplicativo merece.

Perguntas frequentes

Como posso implementar uniões discriminadas em C#?

Em C#, você pode simular uniões discriminadas definindo uma classe base e várias classes derivadas para representar cada caso possível. Essa abordagem, combinada com o casamento de padrões, permite gerenciar com eficiência vários tipos de dados relacionados.

Qual é o papel da correspondência de padrões em uniões discriminadas?

Em C#, o casamento de padrões é crucial ao trabalhar com uniões discriminadas, pois permite lidar com cada caso da união de forma concisa, melhorando a legibilidade do código e reduzindo a necessidade de múltiplas instruções condicionais.

Como as uniões discriminadas se comparam aos enums em C#?

Embora tanto as uniões discriminadas quanto os enums permitam definir um conjunto fixo de opções, as uniões discriminadas oferecem mais flexibilidade, pois podem conter diferentes tipos de dados, enquanto os enums são limitados a constantes nomeadas de um único tipo de dado.

Posso aprimorar a manipulação de dados com o Iron Software ao usar uniões discriminadas?

Sim, produtos da Iron Software como o IronPDF podem complementar uniões discriminadas, fornecendo recursos avançados de manipulação e processamento de dados, facilitando a manipulação e apresentação de diferentes tipos de dados em aplicativos .NET.

Quais são as vantagens de usar uniões discriminadas em C#?

As uniões discriminadas proporcionam maior segurança de tipos, clareza e facilidade de manutenção no seu código C#, permitindo que você defina um tipo com formas possíveis específicas, facilitando a verificação robusta de tipos e reduzindo erros.

Como o uso de uniões discriminadas afeta a legibilidade do código?

Ao permitir que os desenvolvedores definam e manipulem claramente vários tipos de dados relacionados, as uniões discriminadas melhoram a legibilidade do código. O casamento de padrões simplifica ainda mais o código, reduzindo a necessidade de lógica condicional complexa.

Qual a importância de usar classes para simular uniões discriminadas em C#?

Simular uniões discriminadas com classes em C# envolve a criação de uma classe base com classes derivadas para cada caso, permitindo uma forma flexível e expressiva de modelar diferentes tipos relacionados, semelhante às linguagens de programação funcional.

Como as uniões discriminadas podem aprimorar o tratamento de erros em C#?

As uniões discriminadas podem melhorar o tratamento de erros, fornecendo uma verificação de tipos mais precisa e permitindo a correspondência de padrões, o que ajuda a detectar possíveis erros em tempo de compilação, aumentando a confiabilidade do seu aplicativo.

Curtis Chau
Redator Técnico

Curtis Chau é bacharel em Ciência da Computação (Universidade Carleton) e se especializa em desenvolvimento front-end, com experiência em Node.js, TypeScript, JavaScript e React. Apaixonado por criar interfaces de usuário intuitivas e esteticamente agradáveis, Curtis gosta de trabalhar com frameworks modernos e criar manuais ...

Leia mais

Equipe de suporte de ferro

Estamos online 24 horas por dia, 5 dias por semana.
Bater papo
E-mail
Liga para mim