Test dans un environnement réel
Test en production sans filigrane.
Fonctionne partout où vous en avez besoin.
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#.
La recherche de motifs dans le code C# présente une pléthore d'avantages :
La correspondance des motifs est prise en charge par les expressions suivantes :
expressions de commutation
Les motifs suivants peuvent être utilisés pour faire correspondre les constructions :
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
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 :
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
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)),
'};
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
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.
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;
'}
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 Span
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
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
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.
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
static string Classify(double measurement) => measurement switch
{
< -4.0 => "Too low",
> 10.0 => "Too high",
double.NaN => "Unknown",
_ => "Acceptable",
};
Console.WriteLine(Classify(20)); // output: Too high
Console.WriteLine(Classify(double.NaN)); // output: Unknown
Console.WriteLine(Classify(4)); // output: Acceptable
static string Classify(double measurement) => measurement switch
{
< -4.0 => "Too low",
> 10.0 => "Too high",
double.NaN => "Unknown",
_ => "Acceptable",
};
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",
'};
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}."),
'};
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.
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(null)); // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10)); // output: 0.0
static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
DayOfWeek.Monday => 0.5m,
DayOfWeek.Tuesday => 12.5m,
DayOfWeek.Wednesday => 7.5m,
DayOfWeek.Thursday => 12.5m,
DayOfWeek.Friday => 5.0m,
DayOfWeek.Saturday => 2.5m,
DayOfWeek.Sunday => 2.0m,
_ => 0.0m,
};
Console.WriteLine(GetDiscountInPercent(DayOfWeek.Friday)); // output: 5.0
Console.WriteLine(GetDiscountInPercent(null)); // output: 0.0
Console.WriteLine(GetDiscountInPercent((DayOfWeek)10)); // output: 0.0
static decimal GetDiscountInPercent(DayOfWeek? dayOfWeek) => dayOfWeek switch
{
DayOfWeek.Monday => 0.5m,
DayOfWeek.Tuesday => 12.5m,
DayOfWeek.Wednesday => 7.5m,
DayOfWeek.Thursday => 12.5m,
DayOfWeek.Friday => 5.0m,
DayOfWeek.Saturday => 2.5m,
DayOfWeek.Sunday => 2.0m,
_ => 0.0m,
};
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;
'}
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é.
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.
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
Ici, le bloc de code est exécuté si l'entrée n'est pas nulle.
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
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",
};
Console.WriteLine(Classify(13)); // output: High
Console.WriteLine(Classify(-100)); // output: Too low
Console.WriteLine(Classify(5.7)); // output: Acceptable
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",
};
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",
'};
Dans cet exemple, la mesure est classée en fonction de sa plage de valeurs.
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;
' }
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.
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
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."),
'};
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.
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",
'};
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
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.
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
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
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.
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
Install-Package IronPdf
L'image ci-dessous montre comment procéder à l'installation à partir deGuide d'installation de 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
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".
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>"
Placez la clé de licence dans le fichier AppSettings.Json comme indiqué ci-dessus.
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.
9 produits de l'API .NET pour vos documents de bureau