Passer au contenu du pied de page
.NET AIDE

C# Pattern Matching Expressions (Comment ça fonctionne pour les développeurs)

La correspondance de motifs dans C# est une fonctionnalité puissante qui a été introduite dans C# 7.0 et qui a depuis é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, la vérification 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#, notamment la syntaxe, les cas d'utilisation et les exemples de code. À la fin de l'article, nous explorerons également un peu la bibliothèque de génération de PDF IronPDF de Iron Software pour générer un document PDF à la volée dans les applications C#.

Avantages de la recherche de motifs dans C#;

La recherche de motifs dans le code C# présente une pléthore d'avantages :

  • Lisibilité améliorée : la correspondance de modèles simplifie la logique conditionnelle complexe, rendant votre code plus facile à comprendre et à suivre pour vous-même et pour les autres développeurs.
  • Réduction du nombre de lignes de code : en condensant les instructions conditionnelles complexes en modèles concis, la correspondance de modèles contribue à rationaliser votre base de code, ce qui permet de réduire le nombre de lignes de code et d'obtenir une implémentation plus succincte.
  • Maintenabilité améliorée : La clarté offerte par la correspondance de modèles facilite la maintenance et le débogage du code. Les modèles étant clairement définis, 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 de modèles 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, le pattern matching facilite la création d'algorithmes qui ressemblent étroitement à leurs modèles conceptuels.

Types de correspondance de motifs dans C#;

La recherche de motifs est prise en charge par les expressions suivantes :

  • est expression
  • switch déclarations
  • expressions switch

Les modèles suivants peuvent être utilisés pour correspondre aux constructions :

Déclaration et modèles 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 d'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. Considérez 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!
}
$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
}
$vbLabelText   $csharpLabel

Ici, nullableX correspond au modèle car il s'agit d'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(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(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 de placeholder pour tout type correspondant à Vehicle.

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é annulée, comme illustré ci-dessous :

if (inputVal is not null)
{
    // ...
}
if (inputVal is not null)
{
    // ...
}
$vbLabelText   $csharpLabel

Cette négation permet de s'assurer que inputVal n'est pas nul avant de procéder à d'autres 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 les lignes de code et exprimer les algorithmes plus efficacement. Ces modèles constituent 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. Considérez 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)),
};
$vbLabelText   $csharpLabel

Ici, les modèles 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 :

  1. Litres numériques entiers ou à virgule flottante.
  2. Personnages.
  3. Chaînes littérales.
  4. Valeurs booléennes (true ou false).
  5. Valeurs de la liste.
  6. Le nom d'un champ const ou local déclaré.
  7. null .

Une expression de type Span<char> ou ReadOnlySpan<char> peut correspondre à des chaînes constantes.

Pour vérifier la présence de null, utilisez un modèle constant comme suit :

if (inputVal is null)
{
    return;
}
if (inputVal is null)
{
    return;
}
$vbLabelText   $csharpLabel

Ici, le modèle s'assure que inputVal est nul 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)
{
    // ...
}
$vbLabelText   $csharpLabel

Ce modèle vérifie que inputVal n'est pas nul, 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 mises en correspondance, 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. Considérez 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",
};
$vbLabelText   $csharpLabel

Ici, les modèles relationnels comparent la mesure à des seuils spécifiques pour déterminer sa classification.

La partie droite d'un modèle relationnel doit être une expression constante, qui peut être de type entier, virgule flottante, char ou enum. Les opérateurs <, `,<=,>=` peuvent être utilisés sur le côté gauche.

Pour faire correspondre le résultat d'une expression à une plage donnée, utilisez un modèle 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}."),
};
$vbLabelText   $csharpLabel

Cet extrait décrit comment la conjonction "et" est utilisée pour déterminer la saison calendaire en fonction du mois qui se situe dans une fourchette spécifique. Elle 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(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,
};
$vbLabelText   $csharpLabel

Dans l'exemple du modèle de rejet ci-dessus, il traite toutes les valeurs d'entrée possibles. Tous les jours de la semaine sont gérés et une valeur par défaut est fournie. Ainsi, toutes les valeurs possibles sont prises en compte. Le motif Discard ne peut pas être utilisé comme motif dans une expression is ou une instruction switch. Dans de tels cas, un motif var peut être utilisé avec un rejet, comme var _, pour correspondre à n'importe quelle expression. Toutefois, un motif de rejet est autorisé dans une expression switch. 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 (motif not)

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)
{
    // ...
}
$vbLabelText   $csharpLabel

Ici, le bloc de code est exécuté si input n'est pas null.

Conjonctif (modèle et)

Le motif conjonctif, qui utilise le mot-clé et, fait correspondre 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",
};
$vbLabelText   $csharpLabel

Dans cet exemple, la mesure est classée en fonction de sa plage de valeurs.

Disjonctif (motif ou)

Le modèle disjonctif, qui utilise le mot-clé ou, fait correspondre une expression lorsque l'un ou l'autre des modèles 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}."),
};
$vbLabelText   $csharpLabel

Ici, la saison calendaire est déterminée en fonction 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, améliorant ainsi 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. L'extrait de code suivant en est un exemple :

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 };
$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 incorporer une vérification de type à l'exécution et une déclaration de variable dans un modèle de propriété, comme illustré 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."),
};
$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.

Modèle positionnel

En C#, le motif positionnel permet de déconstruire le résultat d'une expression et de faire correspondre les valeurs obtenues à des motifs imbriqués correspondants. {"S":"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",
};
$vbLabelText   $csharpLabel

Dans cet exemple, le modèle positionnel est utilisé pour classer les points en fonction de leurs coordonnées.

En outre, vous pouvez référencer 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 };
$vbLabelText   $csharpLabel

Cette fonctionnalité améliore la flexibilité des modèles de propriété 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 de variable

Var Pattern vous permet de faire correspondre n'importe quel type. Ces outils peuvent être particulièrement utiles 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 démontrant l'utilisation du motif var 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();
}
$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 modèles var peuvent être utilisés dans les expressions ou les déclarations switch pour un code plus concis et plus lisible. Voici un exemple utilisant le 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 }
}
$vbLabelText   $csharpLabel

Dans cet exemple, le motif var (x, y) capture les coordonnées du point, permettant 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, améliorant ainsi la clarté et la flexibilité du code.

Présentation de la Bibliothèque IronPDF

IronPDF Document Rendering 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.

# To install from the NuGet Package Manager Console
Install-Package IronPdf
# To install from the NuGet Package Manager Console
Install-Package IronPdf
SHELL

L'image ci-dessous montre comment procéder à l'installation à partir du Guide d'installation de Visual Studio.

C# Pattern Matching Expressions (How It Works For Developers) : Figure 1 - Installation d'IronPDF avec le gestionnaire de paquets NuGet

Dans le code ci-dessous, nous verrons comment générer un simple document PDF :

using IronPdf;

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>Output: {(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: {season2}</p>";
            var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
            Console.WriteLine(season3);
            content += $"<p>2024, 7, 25: {season3}</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}."),
        };
    }
}
using IronPdf;

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>Output: {(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: {season2}</p>";
            var season3 = GetCalendarSeason(new DateTime(2024, 7, 25));
            Console.WriteLine(season3);
            content += $"<p>2024, 7, 25: {season3}</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}."),
        };
    }
}
$vbLabelText   $csharpLabel

Sortie

C# Pattern Matching Expressions (How It Works For Developers) : Figure 2

Détails du code

Ici, nous utilisons la 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 une licence d'essai obtenue à partir de la page de licence IronPDF. Fournissez une adresse é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>"
$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 tirant parti de la correspondance des modèles, les développeurs peuvent améliorer la clarté et la maintenabilité de leur code tout en réduisant la redondance et les formules passe-partout. 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#, vous permettant d'écrire un code plus propre et plus expressif, plus facile à comprendre et à maintenir. Nous avons également abordé les capacités de génération HTML vers PDF d'IronPDF, qui peuvent être exploitées pour générer des documents PDF.

Questions Fréquemment Posées

Comment puis-je utiliser la correspondance de motif pour améliorer la lisibilité du code en C# ?

La correspondance de motifs en C# permet aux développeurs d'écrire un code plus concis et expressif, rendant les instructions conditionnelles plus claires et plus faciles à comprendre. Cela améliore la lisibilité et la maintenabilité en réduisant la complexité des blocs de code.

Quels sont les différents types d'expressions de correspondance de modèle disponibles en C# ?

C# prend en charge diverses expressions de correspondance de modèle, y compris les expressions is, les instructions switch, et les expressions switch. Chaque type offre différentes manières d'évaluer les expressions et d'exécuter du code en fonction des motifs correspondants.

Comment puis-je générer des documents PDF à l'aide de C# ?

Vous pouvez utiliser IronPDF, une bibliothèque d'Iron Software, pour générer des documents PDF en C#. Il permet la conversion de contenu HTML en PDF et s'installe facilement via NuGet, offrant une large gamme de fonctionnalités de génération de PDF.

Quelles sont les annonces et les motifs de type dans la correspondance de motif C# ?

Les motifs de déclaration et de type en C# vérifient si le type d'exécution d'une expression correspond à un type spécifié et permettent la déclaration d'une nouvelle variable locale lorsqu'une correspondance est réussie, facilitant ainsi les opérations sécurisées par type.

Comment fonctionnent les motifs constants en C# ?

Les motifs constants en C# sont utilisés pour vérifier si une expression est égale à une valeur constante spécifique, telle qu'un entier ou une chaîne, et exécutent une certaine logique si une correspondance est trouvée, permettant des comparaisons de valeurs constantes simples.

Quel est le but des motifs relationnels en C# ?

Les motifs relationnels en C# permettent de comparer les expressions avec des constantes à l'aide d'opérateurs relationnels tels que <, >, <=, et >=. Ceci est utile pour implémenter des vérifications de plage concises dans votre code.

Comment les motifs logiques peuvent-ils être appliqués en C# ?

Les motifs logiques en C# combinent d'autres motifs à l'aide d'opérateurs logiques, tels que et, ou, et non, permettant des conditions de correspondance de motifs complexes pouvant évaluer plusieurs critères simultanément.

Qu'est-ce que le motif de rejet en C# et quand est-il utilisé ?

Le motif de rejet en C#, représenté par _, correspond à toute expression, y compris null, et est couramment utilisé dans les situations où des valeurs spécifiques doivent être ignorées, comme dans les expressions switch.

Comment les motifs de propriété peuvent-ils être utilisés en C# ?

Les motifs de propriété en C# permettent aux développeurs de faire correspondre les propriétés ou champs d'un objet avec des motifs imbriqués, fournissant un moyen d'effectuer des vérifications approfondies de la structure d'un objet tout en maintenant un code clair et concis.

Jacob Mellor, Directeur technique @ Team Iron
Directeur technique

Jacob Mellor est directeur technique chez Iron Software et un ingénieur visionnaire pionnier dans la technologie des PDF en C#. En tant que développeur original derrière la base de code principale d'Iron Software, il a façonné l'architecture du produit de l'entreprise depuis sa création, ...

Lire la suite