Test dans un environnement réel
Test en production sans filigrane.
Fonctionne partout où vous en avez besoin.
Syndicats discriminésles types d'union et de somme, également connus sous le nom de tagged unions ou sum types, représentent un outil puissant pour modéliser des données qui peuvent prendre différentes formes, mais avec des cas possibles bien définis et limités. Bien que C# ne dispose pas d'unions discriminées natives comme certains autres langages(par exemple, F# ou Rust)en ce qui concerne les unions discriminées, vous pouvez simuler des unions discriminées à l'aide de plusieurs techniques de la langue. Dans ce tutoriel, nous allons nous plonger dans les unions discriminées, la façon de les mettre en œuvre en C#, et leur cas d'utilisation pratique avec l'applicationBibliothèque IronPDF.
En termes simples, une union discriminée est un type qui peut contenir plusieurs formes ou valeurs prédéfinies. Il s'agit d'un moyen de créer une structure à sécurité de type qui encapsule différents types ou valeurs tout en garantissant, au moment de la compilation, que seuls les cas valides sont traités.
Imaginez un scénario dans lequel vous souhaitez représenter le résultat d'une opération. L'opération peut soit réussir, en renvoyant des données, soit échouer, en renvoyant un message d'erreur. Une union discriminée vous permettrait de représenter ces deux résultats possibles dans un seul type.
Voici un exemple de simulation d'une union discriminée en C# à l'aide d'une structure de classe :
public abstract class OperationResult<T>
{
private OperationResult() { }
public sealed class Success : OperationResult<T>
{
public T Value { get; }
public Success(T value) => Value = value;
public override string ToString() => $"Success: {Value}";
}
public sealed class Failure : OperationResult<T>
{
public string Error { get; }
public Failure(string error) => Error = error;
public override string ToString() => $"Failure: {Error}";
}
public static OperationResult<T> CreateSuccess(T value) => new Success(value);
public static OperationResult<T> CreateFailure(string error) => new Failure(error);
}
public abstract class OperationResult<T>
{
private OperationResult() { }
public sealed class Success : OperationResult<T>
{
public T Value { get; }
public Success(T value) => Value = value;
public override string ToString() => $"Success: {Value}";
}
public sealed class Failure : OperationResult<T>
{
public string Error { get; }
public Failure(string error) => Error = error;
public override string ToString() => $"Failure: {Error}";
}
public static OperationResult<T> CreateSuccess(T value) => new Success(value);
public static OperationResult<T> CreateFailure(string error) => new Failure(error);
}
Public MustInherit Class OperationResult(Of T)
Private Sub New()
End Sub
Public NotInheritable Class Success
Inherits OperationResult(Of T)
Public ReadOnly Property Value() As T
Public Sub New(ByVal value As T)
Me.Value = value
End Sub
Public Overrides Function ToString() As String
Return $"Success: {Value}"
End Function
End Class
Public NotInheritable Class Failure
Inherits OperationResult(Of T)
Public ReadOnly Property [Error]() As String
Public Sub New(ByVal [error] As String)
Me.Error = [error]
End Sub
Public Overrides Function ToString() As String
Return $"Failure: {[Error]}"
End Function
End Class
Public Shared Function CreateSuccess(ByVal value As T) As OperationResult(Of T)
Return New Success(value)
End Function
Public Shared Function CreateFailure(ByVal [error] As String) As OperationResult(Of T)
Return New Failure([error])
End Function
End Class
Dans cet exemple, OperationResult
C# offre de puissantes capacités de recherche de motifs qui fonctionnent bien avec les unions discriminées. Étendons notre OperationResult
public string HandleResult(OperationResult<int> result) =>
result switch
{
OperationResult<int>.Success success => $"Operation succeeded with value: {success.Value}",
OperationResult<int>.Failure failure => $"Operation failed with error: {failure.Error}",
_ => throw new InvalidOperationException("Unexpected result type")
};
public string HandleResult(OperationResult<int> result) =>
result switch
{
OperationResult<int>.Success success => $"Operation succeeded with value: {success.Value}",
OperationResult<int>.Failure failure => $"Operation failed with error: {failure.Error}",
_ => throw new InvalidOperationException("Unexpected result type")
};
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'public string HandleResult(OperationResult<int> result) => result switch
' {
' OperationResult<int>.Success success => $"Operation succeeded with value: {success.Value}",
' OperationResult<int>.Failure failure => $"Operation failed with error: {failure.Error}",
' _ => throw new InvalidOperationException("Unexpected result type")
' };
L'expression switch utilisée ici traite à la fois les cas de réussite et d'échec du résultat de l'opération (OperationResult)
Vous pouvez étendre la fonctionnalité des unions discriminées à l'aide de méthodes d'extension. Par exemple, créons une méthode d'extension pour notre OperationResult
public static class OperationResultExtensions
{
public static bool IsSuccess<T>(this OperationResult<T> result) =>
result is OperationResult<T>.Success;
}
public static class OperationResultExtensions
{
public static bool IsSuccess<T>(this OperationResult<T> result) =>
result is OperationResult<T>.Success;
}
Public Module OperationResultExtensions
<System.Runtime.CompilerServices.Extension> _
Public Function IsSuccess(Of T)(ByVal result As OperationResult(Of T)) As Boolean
Return TypeOf result Is OperationResult(Of T).Success
End Function
End Module
Cette méthode bool statique publique vérifie si le résultat est une instance du cas Success.
C# ne dispose pas d'une prise en charge native des unions discriminées comme certains autres langages, mais des discussions sont en cours au sein de la communauté pour l'ajout d'une telle fonctionnalité. Les unions discriminées natives faciliteraient la définition et l'utilisation des types d'union sans devoir recourir aux hiérarchies de classes.
L'un des principaux avantages des syndicats discriminés est le type de sécurité qu'ils offrent. Comme tous les cas possibles sont connus au moment de la compilation, le compilateur peut s'assurer que tous les cas sont traités. Cela permet de réduire le nombre d'erreurs d'exécution et de rendre le code moins sujet aux erreurs.
Par exemple, si vous oubliez de traiter un cas spécifique dans une instruction switch, le compilateur produira une erreur, vous invitant à traiter le cas manquant. Cela est particulièrement utile lorsqu'il s'agit de structures de données complexes avec de multiples cas possibles.
IronPDF est une bibliothèque PDF C# qui aide les développeurs àcréer des fichiers PDF à partir de HTML la traduction doit rester professionnelle et préserver l'exactitude technique tout en expliquant les caractéristiques et les avantages de ces outils de développement. Lorsque vous travaillez avec des PDF en C#, vous pouvez intégrer IronPDF avec des unions discriminées pour gérer différents scénarios lors de la génération ou du traitement de fichiers PDF. Par exemple, vous pouvez avoir un processus qui génère un PDF avec succès ou qui rencontre une erreur. Les unions discriminées vous permettent de modéliser clairement ce processus. Créons un exemple simple dans lequel nous générons un PDF à l'aide d'IronPDF et renvoyons le résultat sous la forme d'une union discriminée.
using IronPdf;
using System;
public abstract class PdfResult
{
private PdfResult() { }
public sealed class Success : PdfResult
{
public PdfDocument Pdf { get; }
public Success(PdfDocument pdf) => Pdf = pdf;
public override string ToString() => "PDF generation succeeded";
}
public sealed class Failure : PdfResult
{
public string ErrorMessage { get; }
public Failure(string errorMessage) => ErrorMessage = errorMessage;
public override string ToString() => $"PDF generation failed: {ErrorMessage}";
}
public static PdfResult CreateSuccess(PdfDocument pdf) => new Success(pdf);
public static PdfResult CreateFailure(string errorMessage) => new Failure(errorMessage);
}
public class PdfGenerator
{
public PdfResult GeneratePdf(string htmlContent)
{
try
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
return PdfResult.CreateSuccess(pdf);
}
catch (Exception ex)
{
return PdfResult.CreateFailure(ex.Message);
}
}
}
using IronPdf;
using System;
public abstract class PdfResult
{
private PdfResult() { }
public sealed class Success : PdfResult
{
public PdfDocument Pdf { get; }
public Success(PdfDocument pdf) => Pdf = pdf;
public override string ToString() => "PDF generation succeeded";
}
public sealed class Failure : PdfResult
{
public string ErrorMessage { get; }
public Failure(string errorMessage) => ErrorMessage = errorMessage;
public override string ToString() => $"PDF generation failed: {ErrorMessage}";
}
public static PdfResult CreateSuccess(PdfDocument pdf) => new Success(pdf);
public static PdfResult CreateFailure(string errorMessage) => new Failure(errorMessage);
}
public class PdfGenerator
{
public PdfResult GeneratePdf(string htmlContent)
{
try
{
var renderer = new ChromePdfRenderer();
var pdf = renderer.RenderHtmlAsPdf(htmlContent);
return PdfResult.CreateSuccess(pdf);
}
catch (Exception ex)
{
return PdfResult.CreateFailure(ex.Message);
}
}
}
Imports IronPdf
Imports System
Public MustInherit Class PdfResult
Private Sub New()
End Sub
Public NotInheritable Class Success
Inherits PdfResult
Public ReadOnly Property Pdf() As PdfDocument
Public Sub New(ByVal pdf As PdfDocument)
Me.Pdf = pdf
End Sub
Public Overrides Function ToString() As String
Return "PDF generation succeeded"
End Function
End Class
Public NotInheritable Class Failure
Inherits PdfResult
Public ReadOnly Property ErrorMessage() As String
Public Sub New(ByVal errorMessage As String)
Me.ErrorMessage = errorMessage
End Sub
Public Overrides Function ToString() As String
Return $"PDF generation failed: {ErrorMessage}"
End Function
End Class
Public Shared Function CreateSuccess(ByVal pdf As PdfDocument) As PdfResult
Return New Success(pdf)
End Function
Public Shared Function CreateFailure(ByVal errorMessage As String) As PdfResult
Return New Failure(errorMessage)
End Function
End Class
Public Class PdfGenerator
Public Function GeneratePdf(ByVal htmlContent As String) As PdfResult
Try
Dim renderer = New ChromePdfRenderer()
Dim pdf = renderer.RenderHtmlAsPdf(htmlContent)
Return PdfResult.CreateSuccess(pdf)
Catch ex As Exception
Return PdfResult.CreateFailure(ex.Message)
End Try
End Function
End Class
La classe PdfResult représente une union discriminée avec deux cas : Succès et Échec. Le cas de réussite contient un document Pdf, tandis que le cas d'échec contient un message d'erreur. La méthode GeneratePdf prend une chaîne HTML, tente de générer un PDF à l'aide d'IronPDF et renvoie le résultat sous la forme d'un PdfResult. Si la génération du PDF réussit, il renvoie le cas de réussite avec le PDF généré. Si une exception se produit, elle renvoie le cas d'échec avec le message d'erreur.
Les unions discriminées en C# constituent un moyen puissant et flexible de modéliser des données avec plusieurs cas possibles. Bien que C# ne prenne pas en charge les unions discriminées, vous pouvez les simuler en utilisant des hiérarchies de classes, la correspondance de motifs et d'autres techniques. Le code résultant est plus sûr, moins sujet aux erreurs et plus facile à maintenir.
IronPDF fournit un service deessai gratuit la traduction doit rester professionnelle, tout en préservant l'exactitude technique et en expliquant les caractéristiques et les avantages de ces outils de développement. Vous pouvez explorer toutes les fonctionnalités et voir si elles correspondent à vos besoins. Après votre essai, les licences sont disponibles à partir de 749 $.
9 produits de l'API .NET pour vos documents de bureau