Saltar al pie de página
.NET AYUDA

C# Uniones Discriminadas (Cómo Funciona para Desarrolladores)

Como desarrollador .NET que trabaja con la generación dinámica de PDF utilizando IronPDF, a menudo necesitas representar y gestionar una variedad de tipos específicos: piensa en diferentes tipos de datos de documentos, mensajes de registro, roles de usuario u opciones de exportación. Aquí es donde entra en juego el concepto de una unión discriminada en C#.

Mientras que C# no tiene soporte nativo para uniones discriminadas de la manera en que lo hace F# o Rust, aún puedes simular uniones discriminadas de manera efectiva. En esta publicación de blog, profundizaremos en cómo definir y usar un tipo de unión discriminada en C#, demostraremos cómo aplicarlo con IronPDF para el procesamiento de PDF en el mundo real y exploraremos los beneficios que este patrón proporciona, especialmente cuando se combina con la coincidencia de patrones.

¿Qué son las uniones discriminadas en C#?

Las uniones discriminadas, también conocidas como uniones etiquetadas o tipos de unión, permiten que una variable contenga un valor de un conjunto limitado de opciones posibles, donde cada opción está asociada con un identificador de caso único.

En otros lenguajes como F#, podrías definirlas usando la palabra clave union. C# no proporciona esta característica de manera nativa, pero los desarrolladores pueden usar combinaciones inteligentes de registros, clases y expresiones switch para imitarlas.

Por ejemplo:

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 arriba representa un caso único de la unión. El tipo base PdfAction es el discriminante.

Por qué son importantes las uniones discriminadas en los flujos de trabajo de IronPDF

Imagina que estás construyendo un generador de informes PDF utilizando IronPDF, y necesitas realizar diferentes acciones basadas en la entrada de un usuario, tal vez generar un PDF, registrar un error o exportar datos.

El uso de uniones discriminadas en C# te permite representar estos tipos de opciones limpiamente, lo que lleva a una seguridad en tiempo de compilación, menos errores y una lógica más clara.

Aquí te mostramos cómo podrías usarlo con 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

Este enfoque mantiene tu código organizado y robusto, y facilita que los desarrolladores entiendan todas las opciones posibles en una sola ubicación.

Simulación de uniones discriminadas en C# - Struct vs. Record vs. Class

Aunque C# carece de la palabra clave union, puedes simular uniones discriminadas utilizando:

  • Registros: Ideales para datos inmutables, y soportan coincidir patrones de manera limpia.
  • Clases: Más flexibles con la herencia y semántica de referencia.
  • Estructuras: Útiles para tipos de valor, pero menos flexibles al trabajar con tipos de referencia o herencia.

Uniones Discriminadas en C# (Cómo Funciona para Desarrolladores): Figura 1 - Estructura vs. Registro vs. Clase

Si el rendimiento y la disposición de memoria son importantes —por ejemplo, en el registro de PDF de alto rendimiento— podrías considerar usar estructuras de uniones discriminadas con cuidado:

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

Nota: Perderás algunos beneficios de coincidencia de patrones con estructuras, especialmente al depender de expresiones switch.

Beneficios del uso de uniones discriminadas en C#

Hay varias ventajas clave al adoptar este patrón de ingeniería de software:

  • Seguridad en tiempo de compilación: Detectarás casos faltantes en una expresión switch antes del tiempo de ejecución.
  • Lógica más clara: Es más fácil escribir, comentar y razonar sobre acciones con casos nombrados.
  • Separación de responsabilidades: Desacoplas comportamientos basados en datos en lugar de jerarquías de tipos.
  • Facilidad de refactorización: Agregar o eliminar casos se vuelve más sencillo.

Al combinarlo con IronPDF, esto facilita la gestión de la entrada del usuario, la lógica de renderización o crear plantillas dinámicas con diferentes conductos de valor.

Cuándo utilizar uniones discriminadas con IronPDF

Aquí hay algunos escenarios prácticos donde este patrón sobresale:

  • Flujos de Trabajo de Generación de PDF: Diferentes pasos en el ciclo de vida de un documento (generar, guardar, enviar por correo electrónico).
  • Modelos de Permisos: Representar diferentes niveles de acceso del usuario.
  • Sistemas de Registro: Usar tipos de uniones discriminadas para niveles de registro (información, error, depuración).
  • Pruebas Unitarias: Definir acciones de prueba como tipos de unión para árboles lógicos mantenibles.
  • Opciones de Exportación: Representar objetivos de salida como PDF, Excel, Word como instancias de unión.

Uniones Discriminadas en C# (Cómo Funciona para Desarrolladores): Figura 2 - Escenarios comunes para uniones discriminadas en aplicaciones .NET

Ejemplo - Manejo de acciones PDF a partir de eventos de interfaz de usuario

Supongamos que estás capturando eventos de interfaz de usuario y quieres encaminarlos a tareas de IronPDF usando uniones 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

Esto te permite representar eventos con una lógica clara y reduce la dependencia de tipos de objetos públicos o de manejo excesivamente dinámico.

Perspectivas de futuro - ¿Soportará algún día C&num las uniones discriminadas nativas?

Ya se ha propuesto agregar soporte nativo para uniones discriminadas en C#, especialmente con la creciente demanda de sistemas de tipos más expresivos. Aunque el lenguaje aún no ha introducido una verdadera palabra clave de unión, C# sigue evolucionando, introduciendo características como registros, coincidencia de patrones y expresiones switch más cercanas a la funcionalidad completa de uniones discriminadas.

Los desarrolladores .NET interesados en constructos de lenguaje modernos y amigables para la programación funcional querrán seguir de cerca este espacio.

Reflexiones finales

El uso de uniones discriminadas en C#, incluso sin soporte nativo, puede mejorar significativamente la forma en que estructuras y representas la lógica en aplicaciones de IronPDF. Al aprovechar los registros, expresiones switch y clases base, harás que tu base de código sea más legible, mantenible y resistente a errores, al tiempo que desbloquea una forma más declarativa y expresiva de manejar tareas relacionadas con PDF.

Si eres un ingeniero de software construyendo aplicaciones .NET modernas y flexibles, este patrón es indispensable en tu conjunto de herramientas.

Pruebe IronPDF gratis hoy mismo

¿Listo para llevar tu generación de PDF en C# al siguiente nivel? Descarga IronPDF y comienza con una prueba gratuita. Ya sea que estés generando documentos desde HTML, registrando exportaciones o automatizando informes utilizando uniones discriminadas, IronPDF te ofrece el poder y el rendimiento que tu aplicación merece.

Preguntas Frecuentes

¿Cómo puedo implementar uniones discriminadas en C#?

En C#, puedes simular uniones discriminadas definiendo una clase base y varias clases derivadas para representar cada posible caso. Este enfoque, combinado con coincidencias de patrones, te permite manejar efectivamente múltiples tipos de datos relacionados.

¿Cuál es el papel de la coincidencia de patrones en las uniones discriminadas?

La coincidencia de patrones en C# es crucial al trabajar con uniones discriminadas porque te permite manejar cada caso de la unión de manera concisa, mejorando la legibilidad del código y reduciendo la necesidad de múltiples declaraciones condicionales.

¿Cómo se comparan las uniones discriminadas con los enums en C#?

Aunque tanto las uniones discriminadas como los enums te permiten definir un conjunto fijo de opciones, las uniones discriminadas ofrecen más flexibilidad ya que pueden contener diferentes tipos de datos, mientras que los enums están limitados a constantes nombradas de un solo tipo de dato.

¿Puedo mejorar la manipulación de datos con Iron Software mientras uso uniones discriminadas?

Sí, los productos de Iron Software como IronPDF pueden complementar las uniones discriminadas proporcionando capacidades avanzadas de manejo y procesamiento de datos, facilitando la manipulación y presentación de diferentes tipos de datos en aplicaciones .NET.

¿Cuáles son las ventajas de usar uniones discriminadas en C#?

Las uniones discriminadas proporcionan una mayor seguridad de tipo, claridad y mantenibilidad en tu código C# al permitirse definir un tipo con formas posibles específicas, facilitando la verificación robusta de tipos y reduciendo errores.

¿Cómo afecta el uso de uniones discriminadas a la legibilidad del código?

Permitiendo que los desarrolladores definan y manejen claramente múltiples tipos de datos relacionados, las uniones discriminadas mejoran la legibilidad del código. La coincidencia de patrones simplifica aún más el código al reducir la necesidad de una lógica condicional compleja.

¿Cuál es la importancia de usar clases para simular uniones discriminadas en C#?

Simular uniones discriminadas con clases en C# implica crear una clase base con clases derivadas para cada caso, lo que permite una forma flexible y expresiva de modelar diferentes tipos relacionados, similar a los lenguajes de programación funcional.

¿Cómo pueden las uniones discriminadas mejorar el manejo de errores en C#?

Las uniones discriminadas pueden mejorar el manejo de errores proporcionando una verificación de tipos más precisa y permitiendo la coincidencia de patrones, lo que ayuda a detectar posibles errores en tiempo de compilación, mejorando la fiabilidad de tu aplicación.

Jacob Mellor, Director de Tecnología @ Team Iron
Director de Tecnología

Jacob Mellor es Director de Tecnología en Iron Software y un ingeniero visionario que lidera la tecnología PDF en C#. Como el desarrollador original detrás de la base de código central de Iron Software, ha moldeado la arquitectura de productos de la compañía desde ...

Leer más