using IronPdf;
// Disable local disk access or cross-origin requests
Installation.EnableWebSecurity = true;
// Instantiate Renderer
var renderer = new ChromePdfRenderer();
// Create a PDF from a HTML string using C#
var pdf = renderer.RenderHtmlAsPdf("<h1>Hello World</h1>");
// Export to a file or Stream
pdf.SaveAs("output.pdf");
// Advanced Example with HTML Assets
// Load external html assets: Images, CSS and JavaScript.
// An optional BasePath 'C:\site\assets\' is set as the file location to load assets from
var myAdvancedPdf = renderer.RenderHtmlAsPdf("<img src='icons/iron.png'>", @"C:\site\assets\");
myAdvancedPdf.SaveAs("html-with-assets.pdf");
Expressions de correspondance de motifs en C# (Comment ça marche pour les développeurs)
Chaknith Bin
mars 26, 2024
Partager:
Introduction
La recherche de motifs en C# est une fonctionnalité puissante qui a été introduite en C# 7.0 et qui a été développée dans les versions suivantes. Il permet aux développeurs d'écrire un code plus concis et plus expressif lorsqu'ils utilisent des instructions conditionnelles, des vérifications de type et la déconstruction d'objets.
Les expressions de correspondance de motifs offrent un moyen souple et intuitif de faire correspondre des valeurs à des motifs et d'exécuter les blocs de code correspondants. Dans cet article, nous allons explorer les subtilités des expressions de correspondance de motifs en C#, y compris la syntaxe, les cas d'utilisation et les exemples de code. À la fin de l'article, nous aborderons également les sujets suivantsBibliothèque de génération de PDF IronPDF deIron Software pour générer un document PDF à la volée dans les applications C#.
Avantages de la correspondance des formes en C# ;
La recherche de motifs dans le code C# présente une pléthore d'avantages :
Meilleure lisibilité : La correspondance des motifs simplifie la logique conditionnelle complexe, ce qui rend votre code plus facile à comprendre et à suivre, tant pour vous que pour les autres développeurs.
Réduction des lignes de code : En condensant des instructions conditionnelles complexes en motifs concis, le filtrage par motifs permet de rationaliser votre base de code, ce qui se traduit par un nombre réduit de lignes de code et une mise en œuvre plus succincte.
Amélioration de la maintenabilité : La clarté offerte par la recherche de motifs facilite la maintenance et le débogage du code. Les modèles étant clairement délimités, il devient plus simple d'identifier et de modifier des blocs logiques spécifiques en fonction des besoins, sans affecter le reste de la base de code.
Des algorithmes plus expressifs : La correspondance des motifs permet aux développeurs d'exprimer les algorithmes de manière plus naturelle et intuitive. En alignant les structures de code sur les paradigmes de résolution de problèmes, l'appariement de modèles facilite la création d'algorithmes qui ressemblent étroitement à leurs modèles conceptuels.
Types de correspondance de motifs en C# ;
La correspondance des motifs est prise en charge par les expressions suivantes :
est l'expression
déclarations de commutation
expressions de commutation
Les motifs suivants peuvent être utilisés pour faire correspondre les constructions :
Modèles de déclaration et de type
Les modèles de déclaration et de type sont des outils essentiels en C# pour vérifier la compatibilité des types d'exécution de l'expression avec des types donnés. Avec les modèles de déclaration, vous pouvez à la fois vérifier la compatibilité et déclarer une nouvelle variable locale. Prenons l'exemple suivant :
object greeting = "Iron Software is Awesome!";
if (greeting is string message)
{
Console.WriteLine(message.ToLower()); // output: Iron Software is Awesome!
}
object greeting = "Iron Software is Awesome!";
if (greeting is string message)
{
Console.WriteLine(message.ToLower()); // output: Iron Software is Awesome!
}
Dim greeting As Object = "Iron Software is Awesome!"
Dim tempVar As Boolean = TypeOf greeting Is String
Dim message As String = If(tempVar, DirectCast(greeting, String), Nothing)
If tempVar Then
Console.WriteLine(message.ToLower()) ' output: Iron Software is Awesome!
End If
$vbLabelText $csharpLabel
Ici, le modèle de déclaration garantit que si l'expression greeting correspond au type string, elle est affectée à la variable message, ce qui permet les opérations ultérieures.
Lorsque l'une des conditions suivantes est remplie, le modèle de déclaration est valable :
Le type d'exécution de l'expression est T.
Le type d'exécution de l'expression dérive de T, met en œuvre l'interface T ou peut être implicitement converti en T.
Le type d'exécution de l'expression est un type de valeur nullable avec le type sous-jacent T.
Il existe une conversion de mise en boîte ou de mise hors boîte du type d'exécution de l'expression vers le type T.
Prenons l'exemple suivant, qui illustre les conditions susmentionnées :
int? nullableX = 8;
int y = 45;
object boxedy = y;
if (nullableX is int a && boxedy is int b)
{
Console.WriteLine(a + b); // output: 53
}
int? nullableX = 8;
int y = 45;
object boxedy = y;
if (nullableX is int a && boxedy is int b)
{
Console.WriteLine(a + b); // output: 53
}
Dim nullableX? As Integer = 8
Dim y As Integer = 45
Dim boxedy As Object = y
Dim tempVar As Boolean = TypeOf boxedy Is Integer
Dim b As Integer = If(tempVar, DirectCast(boxedy, Integer), Nothing)
Dim tempVar2 As Boolean = TypeOf nullableX Is Integer
Dim a As Integer = If(tempVar2, CInt(nullableX), Nothing)
If tempVar2 AndAlso tempVar Then
Console.WriteLine(a + b) ' output: 53
End If
$vbLabelText $csharpLabel
Ici, nullableX correspond au motif car c'est un type de valeur nullable avec le type sous-jacent int, et boxedy correspond car il peut être unboxé en int.
Lorsque vous avez seulement besoin de vérifier le type d'une expression sans déclarer une nouvelle variable, vous pouvez utiliser la fonction discard _, comme le montre l'exemple ci-dessous :
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
bus _ => 4.00m,
motor _ => 8.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
{
bus _ => 4.00m,
motor _ => 8.50m,
null => throw new ArgumentNullException(nameof(vehicle)),
_ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
};
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'public static decimal CalculateToll(this Vehicle vehicle) => vehicle switch
'{
' bus _ => 4.00m,
' motor _ => 8.50m,
' null => throw new ArgumentNullException(nameof(vehicle)),
' _ => throw new ArgumentException("Unknown type of a vehicle", nameof(vehicle)),
'};
$vbLabelText $csharpLabel
Dans cet extrait, le _ sert d'espace réservé pour toute correspondance de type Véhicule.
Les motifs de déclaration et de type garantissent que les expressions ne sont pas nulles avant la mise en correspondance des motifs. Vous pouvez vérifier la non-nullité à l'aide d'un modèle de constante nullité inversée, comme illustré ci-dessous :
if (inputVal is not null)
{
// ...
}
if (inputVal is not null)
{
// ...
}
If inputVal IsNot Nothing Then
' ...
End If
$vbLabelText $csharpLabel
Cette négation permet de s'assurer que l'entrée n'est pas nulle avant de poursuivre les opérations.
En exploitant les modèles de déclaration et de type dans votre code C#, vous pouvez améliorer la lisibilité, réduire le nombre de lignes de code et exprimer les algorithmes plus efficacement. Ces modèles fournissent un moyen concis et expressif de gérer la logique basée sur les types et d'améliorer la maintenabilité de votre base de code.
Modèle constant
Les motifs constants permettent de vérifier si le résultat d'une expression correspond à une valeur constante spécifique. Prenons l'exemple suivant :
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
1 => 2.0m,
2 => 10.0m,
3 => 25.0m,
4 => 60.0m,
0 => 0.0m,
_ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
public static decimal GetGroupTicketPrice(int visitorCount) => visitorCount switch
{
1 => 2.0m,
2 => 10.0m,
3 => 25.0m,
4 => 60.0m,
0 => 0.0m,
_ => throw new ArgumentException($"Not supported number of visitors: {visitorCount}", nameof(visitorCount)),
};
Dim tempVar As Decimal
Select Case visitorCount
Case 1
tempVar = 2.0D
Case 2
tempVar = 10.0D
Case 3
tempVar = 25.0D
Case 4
tempVar = 60.0D
Case 0
tempVar = 0.0D
Case Else
'INSTANT VB TODO TASK: Throw expressions are not converted by Instant VB:
'ORIGINAL LINE: tempVar = throw new ArgumentException(string.Format("Not supported number of visitors: {0}", visitorCount), nameof(visitorCount));
tempVar = throw New ArgumentException($"Not supported number of visitors: {visitorCount}", NameOf(visitorCount))
End Select
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'public static decimal GetGroupTicketPrice(int visitorCount)
'{
' Return tempVar;
'}
$vbLabelText $csharpLabel
Ici, les motifs constants vérifient si visitorCount correspond à l'une des valeurs constantes spécifiées et renvoient les prix des billets correspondants.
Dans un modèle constant, vous pouvez utiliser différents types d'expressions constantes, telles que :
Les littéraux numériques entiers ou à virgule flottante.
Personnages.
Chaînes de caractères.
Valeurs booléennes(vrai ou faux).
Valeurs de l'énumération.
Le nom d'un champ const ou local déclaré.
nul.
Une expression de type Spanou ReadOnlySpanpeut correspondre à des chaînes de caractères constantes.
Pour vérifier la présence de nullité, utilisez un modèle constant comme suit :
if (inputVal is null)
{
return;
}
if (inputVal is null)
{
return;
}
If inputVal Is Nothing Then
Return
End If
$vbLabelText $csharpLabel
Ici, le modèle s'assure que l'entrée est nulle avant de procéder à d'autres opérations.
Vous pouvez également utiliser un modèle de constante null négativé pour vérifier les valeurs non nulles :
if (inputVal is not null)
{
// ...
}
if (inputVal is not null)
{
// ...
}
If inputVal IsNot Nothing Then
' ...
End If
$vbLabelText $csharpLabel
Ce modèle vérifie que l'entrée n'est pas nulle, ce qui permet d'effectuer les opérations suivantes en toute sécurité.
En incorporant des modèles de constantes dans votre code C#, vous pouvez gérer efficacement les scénarios dans lesquels des valeurs constantes spécifiques doivent être appariées, améliorant ainsi la clarté et la maintenabilité du code.
Modèles relationnels
Les modèles relationnels permettent de comparer les résultats d'une expression avec des constantes. Prenons l'exemple suivant :
Console.WriteLine(Classify(20)) ' output: Too high
Console.WriteLine(Classify(Double.NaN)) ' output: Unknown
Console.WriteLine(Classify(4)) ' output: Acceptable
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'static string Classify(double measurement) => measurement switch
'{
' < -4.0 => "Too low",
' > 10.0 => "Too high",
' double.NaN => "Unknown",
' _ => "Acceptable",
'};
$vbLabelText $csharpLabel
Ici, les modèles relationnels comparent la mesure à des seuils spécifiques pour déterminer sa classification.
La partie droite d'un motif relationnel doit être une expression constante, qui peut être de type entier, flottant, char ou enum. Les opérateurs <, >, <=, ou >= peuvent être utilisés du côté gauche.
Pour faire correspondre le résultat d'une expression à l'intérieur d'une certaine plage, utilisez un motif conjonctif et, comme illustré ci-dessous :
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 3, 12))); // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 7, 12))); // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 2, 12))); // output: winter
static string GetCalendarSeason(DateTime date) => date.Month switch
{
>= 3 and < 6 => "spring",
>= 6 and < 9 => "summer",
>= 9 and < 12 => "autumn",
12 or (>= 1 and < 3) => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 3, 12))); // output: spring
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 7, 12))); // output: summer
Console.WriteLine(GetCalendarSeason(new DateTime(2024, 2, 12))); // output: winter
static string GetCalendarSeason(DateTime date) => date.Month switch
{
>= 3 and < 6 => "spring",
>= 6 and < 9 => "summer",
>= 9 and < 12 => "autumn",
12 or (>= 1 and < 3) => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Console.WriteLine(GetCalendarSeason(New DateTime(2024, 3, 12))) ' output: spring
Console.WriteLine(GetCalendarSeason(New DateTime(2024, 7, 12))) ' output: summer
Console.WriteLine(GetCalendarSeason(New DateTime(2024, 2, 12))) ' output: winter
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'static string GetCalendarSeason(DateTime date) => date.Month switch
'{
' >= 3 and < 6 => "spring",
' >= 6 and < 9 => "summer",
' >= 9 and < 12 => "autumn",
' 12 or (>= 1 and < 3) => "winter",
' _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
'};
$vbLabelText $csharpLabel
Cet extrait décrit comment le motif conjonctif "et" est utilisé pour déterminer la saison calendaire en fonction du mois qui se situe dans des fourchettes spécifiques. Il mentionne également que les modèles relationnels fournissent un moyen concis et expressif de comparer les résultats d'une expression à des constantes, améliorant ainsi la clarté et la maintenabilité du code.
Modèle de rejet
Le motif de rejet, désigné par _, permet de faire correspondre n'importe quelle expression, y compris null. Prenons l'exemple suivant :
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday)) ' output: 5.0
Console.WriteLine(GetDiscountInPercent(Nothing)) ' output: 0.0
Console.WriteLine(GetDiscountInPercent(CType(10, DayOfWeek))) ' output: 0.0
Dim tempVar As Decimal
Select Case dayOfWeek
Case DayOfWeek.Monday
tempVar = 0.5D
Case DayOfWeek.Tuesday
tempVar = 12.5D
Case DayOfWeek.Wednesday
tempVar = 7.5D
Case DayOfWeek.Thursday
tempVar = 12.5D
Case DayOfWeek.Friday
tempVar = 5.0D
Case DayOfWeek.Saturday
tempVar = 2.5D
Case DayOfWeek.Sunday
tempVar = 2.0D
Case Else
tempVar = 0.0D
End Select
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
'static decimal GetDiscountInPercent(System.Nullable(Of DayOfWeek) dayOfWeek)
'{
' Return tempVar;
'}
$vbLabelText $csharpLabel
Dans le modèle de rejet, l'exemple ci-dessus traite toutes les valeurs d'entrée possibles. Tous les jours de la semaine sont traités et représentent la valeur par défaut. Toutes les valeurs possibles sont ainsi traitées. Le motif de rejet ne peut pas être utilisé comme motif dans une expression is ou une instruction switch. Dans ce cas, vous pouvez utiliser un motif var avec un rejet, comme var _, pour faire correspondre n'importe quelle expression. Toutefois, un motif de rejet est autorisé dans une expression de commutation. Pour plus de détails, veuillez vous référer à la section "Discard pattern" de la note de proposition de fonctionnalité.
Modèles logiques
Les motifs logiques en C# offrent des outils puissants pour la correspondance des motifs, notamment la négation, la conjonction et la disjonction, qui permettent des conditions de correspondance plus souples et plus expressives.
Négation (pas de modèle)
Le motif de négation, représenté par "not", correspond à une expression lorsque le motif nié ne correspond pas à l'expression. Ceci est particulièrement utile pour vérifier si une expression est non nulle, comme démontré ci-dessous :
if (input is not null)
{
// ...
}
if (input is not null)
{
// ...
}
If input IsNot Nothing Then
' ...
End If
$vbLabelText $csharpLabel
Ici, le bloc de code est exécuté si l'entrée n'est pas nulle.
Conjonctif (et modèle)
Le motif conjonctif, qui utilise le mot-clé "et", correspond à une expression lorsque les deux motifs correspondent à l'expression. Cela permet de combiner plusieurs conditions, comme l'illustre l'exemple suivant :
Console.WriteLine(Classify(13)) ' output: High
Console.WriteLine(Classify(-100)) ' output: Too low
Console.WriteLine(Classify(5.7)) ' output: Acceptable
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'static string Classify(double measurement) => measurement switch
'{
' < -40.0 => "Too low",
' >= -40.0 and < 0 => "Low",
' >= 0 and < 10.0 => "Acceptable",
' >= 10.0 and < 20.0 => "High",
' >= 20.0 => "Too high",
' double.NaN => "Unknown",
'};
$vbLabelText $csharpLabel
Dans cet exemple, la mesure est classée en fonction de sa plage de valeurs.
Disjonctive (ou modèle)
Le motif disjonctif, qui utilise le mot-clé "ou", correspond à une expression lorsque l'un ou l'autre des motifs correspond à l'expression. Cela permet de traiter plusieurs conditions possibles, comme indiqué ci-dessous :
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19))); // output: winter
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9))); // output: autumn
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11))); // output: spring
static string GetCalendarSeason(DateTime date) => date.Month switch
{
3 or 4 or 5 => "spring",
6 or 7 or 8 => "summer",
9 or 10 or 11 => "autumn",
12 or 1 or 2 => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 1, 19))); // output: winter
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 10, 9))); // output: autumn
Console.WriteLine(GetCalendarSeason(new DateTime(2021, 5, 11))); // output: spring
static string GetCalendarSeason(DateTime date) => date.Month switch
{
3 or 4 or 5 => "spring",
6 or 7 or 8 => "summer",
9 or 10 or 11 => "autumn",
12 or 1 or 2 => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
Console.WriteLine(GetCalendarSeason(New DateTime(2021, 1, 19))) ' output: winter
Console.WriteLine(GetCalendarSeason(New DateTime(2021, 10, 9))) ' output: autumn
Console.WriteLine(GetCalendarSeason(New DateTime(2021, 5, 11))) ' output: spring
Dim tempVar As String
Select Case [date].Month
Case 3, 4, 5
tempVar = "spring"
Case 6, 7, 8
tempVar = "summer"
Case 9, 10, 11
tempVar = "autumn"
Case 12, 1, 2
tempVar = "winter"
Case Else
'INSTANT VB TODO TASK: Throw expressions are not converted by Instant VB:
'ORIGINAL LINE: tempVar = throw new ArgumentOutOfRangeException(nameof(date), string.Format("Date with unexpected month: {0}.", date.Month));
tempVar = throw New ArgumentOutOfRangeException(NameOf([date]), $"Date with unexpected month: {[date].Month}.")
End Select
'INSTANT VB TODO TASK: Local functions are not converted by Instant VB:
' static string GetCalendarSeason(DateTime @date)
' {
' Return tempVar;
' }
$vbLabelText $csharpLabel
Ici, la saison calendaire est déterminée sur la base du mois de la date fournie.
Ces combinateurs de motifs peuvent être utilisés à plusieurs reprises pour créer des conditions de correspondance plus complexes et plus précises, ce qui améliore la flexibilité et la lisibilité de votre code.
Modèle de propriété
Le motif de propriété permet de faire correspondre les propriétés ou les champs d'une expression à des motifs imbriqués. Un exemple de ceci peut être vu dans l'extrait de code suivant :
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
static bool IsConferenceDay(DateTime date) => date is { Year: 2020, Month: 5, Day: 19 or 20 or 21 };
Shared Function IsConferenceDay(ByVal [date] As DateTime) As Boolean
'INSTANT VB TODO TASK: The following 'is' operator pattern is not converted by Instant VB:
Return [date] is { Year: 2020, Month: 5, Day: 19 [or] 20 [or] 21 }
End Function
$vbLabelText $csharpLabel
Ici, le modèle de propriété garantit que la date fournie correspond à l'un des jours de conférence spécifiés.
Vous pouvez également intégrer une vérification de type à l'exécution et une déclaration de variable dans un modèle de propriété, comme indiqué ci-dessous :
static string TakeFive(object input) => input switch
{
string { Length: >= 5 } s => s.Substring(0, 5),
string s => s,
ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
ICollection<char> symbols => new string(symbols.ToArray()),
null => throw new ArgumentNullException(nameof(input)),
_ => throw new ArgumentException("Unsupported input type."),
};
static string TakeFive(object input) => input switch
{
string { Length: >= 5 } s => s.Substring(0, 5),
string s => s,
ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
ICollection<char> symbols => new string(symbols.ToArray()),
null => throw new ArgumentNullException(nameof(input)),
_ => throw new ArgumentException("Unsupported input type."),
};
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'static string TakeFive(object input) => input switch
'{
' string { Length: >= 5 } s => s.Substring(0, 5),
' string s => s,
' ICollection<char> { Count: >= 5 } symbols => new string(symbols.Take(5).ToArray()),
' ICollection<char> symbols => new string(symbols.ToArray()),
' null => throw new ArgumentNullException(nameof(input)),
' _ => throw new ArgumentException("Unsupported input type."),
'};
$vbLabelText $csharpLabel
Ici, le modèle de propriété est utilisé pour gérer les chaînes de caractères et les collections de caractères, en garantissant un traitement approprié en fonction de leurs propriétés.
Schéma de positionnement
En C#, le motif positionnel permet de déconstruire le résultat d'une expression et de faire correspondre les valeurs résultantes à des motifs imbriqués correspondants. Par exemple :
public readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
static string Classify(Point point) => point switch
{
(0, 0) => "Origin",
(1, 0) => "Positive X basis end",
(0, 1) => "Positive Y basis end",
_ => "Just a point",
};
public readonly struct Point
{
public int X { get; }
public int Y { get; }
public Point(int x, int y) => (X, Y) = (x, y);
public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
}
static string Classify(Point point) => point switch
{
(0, 0) => "Origin",
(1, 0) => "Positive X basis end",
(0, 1) => "Positive Y basis end",
_ => "Just a point",
};
'INSTANT VB WARNING: VB has no equivalent to the C# readonly struct:
'ORIGINAL LINE: public readonly struct Point
Public Structure Point
Public ReadOnly Property X() As Integer
Public ReadOnly Property Y() As Integer
Public Sub New(ByVal x As Integer, ByVal y As Integer)
'INSTANT VB TODO TASK: VB has no equivalent to the C# deconstruction assignments:
(X, Y) = (x, y)
End Sub
Public Sub Deconstruct(<System.Runtime.InteropServices.Out()> ByRef x As Integer, <System.Runtime.InteropServices.Out()> ByRef y As Integer)
'INSTANT VB TODO TASK: VB has no equivalent to the C# deconstruction assignments:
(x, y) = (X, Y)
End Sub
End Structure
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'static string Classify(Point point) => point switch
'{
' (0, 0) => "Origin",
' (1, 0) => "Positive X basis end",
' (0, 1) => "Positive Y basis end",
' _ => "Just a point",
'};
$vbLabelText $csharpLabel
Dans cet exemple, le modèle de position est utilisé pour classer les points en fonction de leurs coordonnées.
En outre, vous pouvez faire référence à des propriétés ou à des champs imbriqués dans un modèle de propriété, connu sous le nom de modèle de propriété étendu, introduit dans C# 10 :
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start.Y: 0 } or { End.Y: 0 };
static bool IsAnyEndOnXAxis(Segment segment) =>
segment is { Start.Y: 0 } or { End.Y: 0 };
Shared Function IsAnyEndOnXAxis(ByVal segment As Segment) As Boolean
'INSTANT VB TODO TASK: The following 'is' operator pattern is not converted by Instant VB:
Return segment is { Start.Y: 0 } [or] { [End].Y: 0 }
End Function
$vbLabelText $csharpLabel
Cette fonctionnalité améliore la flexibilité des modèles de propriétés en permettant un accès direct aux propriétés imbriquées.
Ces modèles fournissent des mécanismes puissants pour gérer des structures de données complexes et améliorer la lisibilité et l'expressivité de votre code.
Modèle Var
Var Pattern vous permet de faire correspondre n'importe quel type. Cela peut être particulièrement utile pour capturer des résultats intermédiaires dans des expressions booléennes ou lorsque des vérifications multiples sont nécessaires dans des gardes de cas de commutation.
Voici un exemple illustrant l'utilisation de var pattern dans une expression booléenne :
static bool IsAcceptable(int id, int absLimit) =>
SimulateDataFetch(id) is var results
&& results.Min() >= -absLimit
&& results.Max() <= absLimit;
static int [] SimulateDataFetch(int id)
{
var rand = new Random();
return Enumerable
.Range(start: 0, count: 5)
.Select(s => rand.Next(minValue: -10, maxValue: 11))
.ToArray();
}
static bool IsAcceptable(int id, int absLimit) =>
SimulateDataFetch(id) is var results
&& results.Min() >= -absLimit
&& results.Max() <= absLimit;
static int [] SimulateDataFetch(int id)
{
var rand = new Random();
return Enumerable
.Range(start: 0, count: 5)
.Select(s => rand.Next(minValue: -10, maxValue: 11))
.ToArray();
}
Shared Function IsAcceptable(ByVal id As Integer, ByVal absLimit As Integer) As Boolean
Dim tempVar As Boolean = TypeOf SimulateDataFetch(id) Is var
Dim results = If(tempVar, CType(SimulateDataFetch(id), var), Nothing)
Return tempVar AndAlso results.Min() >= -absLimit AndAlso results.Max() <= absLimit
End Function
Shared Function SimulateDataFetch(ByVal id As Integer) As Integer()
Dim rand = New Random()
Return Enumerable.Range(start:= 0, count:= 5).Select(Function(s) rand.Next(minValue:= -10, maxValue:= 11)).ToArray()
End Function
$vbLabelText $csharpLabel
Dans cet exemple, SimulateDataFetch renvoie un tableau d'entiers, et le motif is var capture le résultat dans la variable results, permettant des calculs ultérieurs basés sur ses propriétés.
En outre, les motifs var peuvent être utilisés dans des expressions ou des instructions de commutation pour un code plus concis et plus lisible. Voici un exemple d'utilisation du motif var dans les gardes de cas de commutation :
public record Point(int X, int Y);
static Point Transform(Point point) => point switch
{
var (x, y) when x < y => new Point(-x, y),
var (x, y) when x > y => new Point(x, -y),
var (x, y) => new Point(x, y),
};
static void TestTransform()
{
Console.WriteLine(Transform(new Point(1, 2))); // output: Point { X = -1, Y = 2 }
Console.WriteLine(Transform(new Point(5, 2))); // output: Point { X = 5, Y = -2 }
}
public record Point(int X, int Y);
static Point Transform(Point point) => point switch
{
var (x, y) when x < y => new Point(-x, y),
var (x, y) when x > y => new Point(x, -y),
var (x, y) => new Point(x, y),
};
static void TestTransform()
{
Console.WriteLine(Transform(new Point(1, 2))); // output: Point { X = -1, Y = 2 }
Console.WriteLine(Transform(new Point(5, 2))); // output: Point { X = 5, Y = -2 }
}
'INSTANT VB TODO TASK: C# 'records' are not converted by Instant VB:
'public record Point(int X, int Y)
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
'static Point Transform(Point point) => point switch
'{
' var (x, y) when x < y => new Point(-x, y),
' var (x, y) when x > y => new Point(x, -y),
' var (x, y) => new Point(x, y),
'};
Shared Sub TestTransform()
Console.WriteLine(Transform(New Point(1, 2))) ' output: Point { X = -1, Y = 2 }
Console.WriteLine(Transform(New Point(5, 2))) ' output: Point { X = 5, Y = -2 }
End Sub
$vbLabelText $csharpLabel
Dans cet exemple, le motif var(x, y) capture les coordonnées du point, permettant ainsi différentes transformations basées sur leurs valeurs.
Dans un motif var, le type de la variable déclarée est déduit du type à la compilation de l'expression correspondant au motif.
Le modèle var offre un moyen pratique de gérer divers scénarios dans lesquels le type spécifique d'expression n'est pas connu à l'avance, ce qui améliore la clarté et la flexibilité du code.
Présentation de la bibliothèque IronPDF
Rendu de documents IronPDF est une bibliothèque d'Iron Software spécialisée dans la génération de documents PDF. Pour commencer, la première chose à faire est d'installer la bibliothèque à partir du gestionnaire de paquets NuGet ou du gestionnaire de paquets Visual Studio
Dans le code ci-dessous, nous verrons comment générer un simple document PDF :
namespace IronPatterns;
class Program
{
static void Main()
{
Console.WriteLine("-----------Iron Software-------------");
var renderer = new ChromePdfRenderer(); // var pattern
var content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!";
// Declaration Pattern
int? nullableX = 8;
int y = 45;
object boxedy = y;
content += "<p>Declaration Pattern</p>";
if (nullableX is int a && boxedy is int b)
{
Console.WriteLine(a + b); // output: 53
content += $"<p>Ouput:{(a + b)}</p>";
}
//Relational patterns
content += "<p>Relational patterns</p>";
var season1 = GetCalendarSeason(new DateTime(2024, 2, 25));
Console.WriteLine(season1);
content += $"<p>2024, 2, 25:{season1}</p>";
var season2 = GetCalendarSeason(new DateTime(2024, 5, 25));
Console.WriteLine(season2);
content += $"<p>2024, 5, 25:{season1}</p>";
var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
Console.WriteLine(season3);
content += $"<p>2024, 7, 25:{season1}</p>";
var pdf = renderer.RenderHtmlAsPdf(content);
pdf.SaveAs("output.pdf"); // Saves our PdfDocument object as a PDF
}
static string GetCalendarSeason(DateTime date) => date.Month switch
{
>= 3 and < 6 => "spring",
>= 6 and < 9 => "summer",
>= 9 and < 12 => "autumn",
12 or (>= 1 and < 3) => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
}
namespace IronPatterns;
class Program
{
static void Main()
{
Console.WriteLine("-----------Iron Software-------------");
var renderer = new ChromePdfRenderer(); // var pattern
var content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!";
// Declaration Pattern
int? nullableX = 8;
int y = 45;
object boxedy = y;
content += "<p>Declaration Pattern</p>";
if (nullableX is int a && boxedy is int b)
{
Console.WriteLine(a + b); // output: 53
content += $"<p>Ouput:{(a + b)}</p>";
}
//Relational patterns
content += "<p>Relational patterns</p>";
var season1 = GetCalendarSeason(new DateTime(2024, 2, 25));
Console.WriteLine(season1);
content += $"<p>2024, 2, 25:{season1}</p>";
var season2 = GetCalendarSeason(new DateTime(2024, 5, 25));
Console.WriteLine(season2);
content += $"<p>2024, 5, 25:{season1}</p>";
var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
Console.WriteLine(season3);
content += $"<p>2024, 7, 25:{season1}</p>";
var pdf = renderer.RenderHtmlAsPdf(content);
pdf.SaveAs("output.pdf"); // Saves our PdfDocument object as a PDF
}
static string GetCalendarSeason(DateTime date) => date.Month switch
{
>= 3 and < 6 => "spring",
>= 6 and < 9 => "summer",
>= 9 and < 12 => "autumn",
12 or (>= 1 and < 3) => "winter",
_ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
};
}
Namespace IronPatterns
Friend Class Program
Shared Sub Main()
Console.WriteLine("-----------Iron Software-------------")
Dim renderer = New ChromePdfRenderer() ' var pattern
Dim content = " <h1> Iron Software is Awesome </h1> Made with IronPDF!"
' Declaration Pattern
Dim nullableX? As Integer = 8
Dim y As Integer = 45
Dim boxedy As Object = y
content &= "<p>Declaration Pattern</p>"
Dim tempVar As Boolean = TypeOf boxedy Is Integer
Dim b As Integer = If(tempVar, DirectCast(boxedy, Integer), Nothing)
Dim tempVar2 As Boolean = TypeOf nullableX Is Integer
Dim a As Integer = If(tempVar2, CInt(nullableX), Nothing)
If tempVar2 AndAlso tempVar Then
Console.WriteLine(a + b) ' output: 53
content &= $"<p>Ouput:{(a + b)}</p>"
End If
'Relational patterns
content &= "<p>Relational patterns</p>"
Dim season1 = GetCalendarSeason(New DateTime(2024, 2, 25))
Console.WriteLine(season1)
content &= $"<p>2024, 2, 25:{season1}</p>"
Dim season2 = GetCalendarSeason(New DateTime(2024, 5, 25))
Console.WriteLine(season2)
content &= $"<p>2024, 5, 25:{season1}</p>"
Dim season3 = GetCalendarSeason(New DateTime(2024, 7, 25))
Console.WriteLine(season3)
content &= $"<p>2024, 7, 25:{season1}</p>"
Dim pdf = renderer.RenderHtmlAsPdf(content)
pdf.SaveAs("output.pdf") ' Saves our PdfDocument object as a PDF
End Sub
'INSTANT VB TODO TASK: The following 'switch expression' was not converted by Instant VB:
' static string GetCalendarSeason(DateTime date) => date.Month switch
' {
' >= 3 and < 6 => "spring",
' >= 6 and < 9 => "summer",
' >= 9 and < 12 => "autumn",
' 12 or (>= 1 and < 3) => "winter",
' _ => throw new ArgumentOutOfRangeException(nameof(date), $"Date with unexpected month: {date.Month}."),
' };
End Class
End Namespace
$vbLabelText $csharpLabel
Sortie
Détails du code
Nous utilisons iciLa classe ChromePdfRenderer d'IronPDF pour enregistrer la chaîne HTML dans un document PDF. Le résultat est enregistré dans le document "output.pdf".
Licence d'essai
IronPDF peut être utilisé avec unlicence d'essai obtenu à partir de laPage de licence IronPDF. Fournissez un identifiant de courrier électronique pour générer une clé de licence qui vous sera envoyée par courrier électronique.
"IronPDF.LicenseKey": "<Your Key>"
"IronPDF.LicenseKey": "<Your Key>"
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'"IronPDF.LicenseKey": "<Your Key>"
$vbLabelText $csharpLabel
Placez la clé de licence dans le fichier AppSettings.Json comme indiqué ci-dessus.
Conclusion
Les expressions de correspondance de motifs en C# offrent un moyen puissant et flexible d'écrire des instructions conditionnelles, des vérifications de type et des déconstructions d'objets de manière concise et lisible. En s'appuyant sur la recherche de motifs, les développeurs peuvent améliorer la clarté et la facilité de maintenance de leur code tout en réduisant les répétitions et les redondances. Qu'il s'agisse de vérification de type, d'instructions de commutation ou de déconstruction, les expressions de correspondance de motifs constituent un ensemble d'outils polyvalents permettant de s'attaquer à un large éventail de tâches de programmation en C#.
En conclusion, la maîtrise des expressions de correspondance de motifs peut grandement améliorer vos compétences en programmation C#, en vous permettant d'écrire un code plus propre et plus expressif, plus facile à comprendre et à maintenir. Nous avons également couvertCapacités de génération de HTML en PDF d'IronPDFla 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.
Chaknith travaille sur IronXL et IronBarcode. Il possède une expertise approfondie en C# et .NET, aidant à améliorer le logiciel et à soutenir les clients. Ses idées issues des interactions avec les utilisateurs contribuent à de meilleurs produits, une documentation améliorée et une expérience globale enrichie.
< PRÉCÉDENT .NET Software Development (How It Works For Developers) (Développement de logiciels .NET (Comment cela fonctionne pour les développeurs))
SUIVANT > C# interne (Comment ça marche pour les développeurs)
Des millions d'ingénieurs dans le monde entier lui font confiance
Réservez une démo en direct gratuite
Réservez une démonstration personnelle de 30 minutes.
Pas de contrat, pas de détails de carte, pas d'engagements.
Voici ce à quoi vous pouvez vous attendre :
Une démonstration en direct de notre produit et de ses principales fonctionnalités
Obtenez des recommandations de fonctionnalités spécifiques au projet
Toutes vos questions trouvent réponse pour vous assurer de disposer de toutes les informations dont vous avez besoin. (Aucun engagement de votre part.)
CHOISIR L'HEURE
VOS INFORMATIONS
Réservez votre démo en direct gratuite
Fiable par plus de 2 millions d'ingénieurs dans le monde entier