Zum Fußzeileninhalt springen
.NET HILFE

In diesem Artikel tauchen wir tief in die Komplexität des C# LINQ Join-Operators ein und erklären seine Funktionalität, Syntax und Anwendungen.

Mustererkennung in C# ist ein leistungsstarkes Feature, das in C# 7.0 eingeführt und seitdem in nachfolgenden Versionen erweitert wurde. Es ermöglicht Entwicklern, prägnanteren und ausdrucksstärkeren Code zu schreiben, wenn es um bedingte Anweisungen, Typprüfung und die Zerlegung von Objekten geht.

Mustererkennungsausdrücke bieten eine flexible und intuitive Möglichkeit, Werte mit Mustern abzugleichen und entsprechende Codeblöcke auszuführen. In diesem Artikel werden wir die Feinheiten der Mustererkennungsausdrücke in C# erkunden, einschließlich Syntax, Anwendungsfällen und Codebeispielen. Am Ende des Artikels werden wir auch ein wenig über IronPDF PDF Erstellung Bibliothek von Iron Software sprechen, um ein PDF-Dokument in C#-Anwendungen spontan zu erstellen.

Vorteile von Pattern Matching in C

Mustererkennung in C#-Code bietet eine Fülle von Vorteilen:

  • Verbesserte Lesbarkeit: Mustererkennung vereinfacht komplexe bedingte Logik und macht Ihren Code sowohl für Sie selbst als auch für andere Entwickler leichter verständlich und nachvollziehbar.
  • Reduzierung der Codezeilen: Durch die Zusammenfassung komplexer bedingter Anweisungen in prägnante Muster trägt das Pattern Matching zur Optimierung Ihrer Codebasis bei, was zu weniger Codezeilen und einer kompakteren Implementierung führt.
  • Verbesserte Wartbarkeit: Die durch Pattern Matching erzielte Klarheit fördert eine einfachere Code-Wartung und Fehlersuche. Mit klar abgegrenzten Mustern wird es einfacher, bestimmte Logikblöcke bei Bedarf zu identifizieren und zu ändern, ohne den restlichen Code zu beeinträchtigen.
  • Ausdrucksstärkere Algorithmen: Mustererkennung versetzt Entwickler in die Lage, Algorithmen auf natürlichere und intuitivere Weise auszudrücken. Durch die Ausrichtung von Code-Strukturen auf Problemlösungs-Paradigmen erleichtert die Mustererkennung die Erstellung von Algorithmen, die ihren konzeptuellen Modellen sehr nahe kommen.

Arten des Pattern Matching in C

Mustererkennung wird durch folgende Ausdrücke unterstützt:

  • is Ausdruck
  • switch Anweisungen
  • switch Ausdrücke

Die folgenden Muster können zum Abgleich mit den Konstrukten verwendet werden:

Deklaration und Typenmuster

Deklarations- und Typenmuster sind wesentliche Werkzeuge in C#, um die Kompatibilität von Ausführungszeit-Typen von Ausdrücken mit gegebenen Typen zu überprüfen. Mit Deklarationsmustern können Sie sowohl die Kompatibilität prüfen als auch gleichzeitig eine neue lokale Variable deklarieren. Beispiel: IronPDF rendert HTML zu einem PDF und speichert es.

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

Hier sorgt das Deklarationsmuster dafür, dass, wenn das Ausdruck greeting mit dem Typ string übereinstimmt, es der Variablen message zugewiesen wird, was nachfolgende Operationen ermöglicht.

Wenn eine der folgenden Bedingungen zutrifft, hält das Deklarationsmuster stand:

  • Der Ausführungszeit-Typ des Ausdrucks ist T.
  • Der Ausführungszeit-Typ des Ausdrucks leitet sich von T ab, implementiert das Interface T oder kann implizit in T konvertiert werden.
  • Der Ausführungszeit-Typ des Ausdrucks ist ein Nullable-Typ mit dem zugrunde liegenden Typ T.
  • Eine Boxing- oder Unboxing-Konvertierung existiert vom Ausführungszeit-Typ des Ausdrucks zu Typ T.

Betrachten Sie das folgende Beispiel, das die oben genannten Bedingungen demonstriert:

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

Hier entspricht nullableX dem Muster, da es sich um einen Nullable-Typ mit dem zugrunde liegenden Typ int handelt, und boxedy stimmt überein, weil es auf int entpackt werden kann.

Wenn Sie nur den Typ des Ausdrucks überprüfen müssen, ohne eine neue Variable zu deklarieren, können Sie das Discard _ verwenden, wie im folgenden Beispiel zu sehen:

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

In diesem Ausschnitt dient das _ als Platzhalter für einen beliebigen Typ, der mit Fahrzeug übereinstimmt.

Sowohl Deklarations- als auch Typenmuster stellen sicher, dass Ausdrücke vor der Mustererkennung nicht null sind. Sie können auf Nicht-Null prüfen, indem Sie ein verneintes Nullkonstantenmuster verwenden, wie unten gezeigt:

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

Diese Negation stellt sicher, dass inputVal nicht null ist, bevor mit weiteren Operationen fortgefahren wird.

Durch den Einsatz von Deklarations- und Typenmustern in Ihrem C#-Code können Sie die Lesbarkeit verbessern, Codezeilen reduzieren und Algorithmen effektiver ausdrücken. Diese Muster bieten eine prägnante und ausdrucksstarke Möglichkeit zur Handhabung typbasierter Logik und verbessern die Wartbarkeit Ihrer Codebasis.

Konstante Muster

Konstantenmuster dienen dazu, zu überprüfen, ob ein Ausdrucksergebnis einem bestimmten Konstantenwert entspricht. Beispiel: IronPDF rendert HTML zu einem PDF und speichert es.

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

Hier prüfen die Konstantenmuster, ob visitorCount einem der angegebenen Konstantenwerte entspricht und geben entsprechende Ticketpreise zurück.

In einem Konstantenmuster können Sie verschiedene Arten von Konstantenausdrücken verwenden, wie:

  1. Ganze oder Fließkomma-Zahlenliterale.
  2. Zeichen.
  3. Zeichenfolgenliterale.
  4. Boolesche Werte (true oder false).
  5. Enumerationswerte.
  6. Der Name eines deklarierten Const-Felds oder lokals.
  7. null.

Ein Ausdruck des Typs Span<char> oder ReadOnlySpan<char> kann auf konstanten Zeichenfolgen abgestimmt werden.

Um null zu überprüfen, verwenden Sie ein Konstantenmuster wie folgt:

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

Hier stellt das Muster sicher, dass inputVal null ist, bevor mit weiteren Operationen fortgefahren wird.

Sie können auch ein verneintes Nullkonstantenmuster verwenden, um nicht-null Werte zu bestimmen:

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

Dieses Muster überprüft, ob inputVal nicht null ist, wodurch nachfolgende Operationen sicher durchgeführt werden können.

Indem Sie Konstantenmuster in Ihren C#-Code integrieren, können Sie Szenarien effektiv verwalten, in denen bestimmte Konstantenwerte abgeglichen werden müssen, wodurch die Codeklarheit und Wartbarkeit verbessert wird.

Relationale Schemata

Relationale Muster bieten eine Möglichkeit, Ausdrucksergebnisse mit Konstanten zu vergleichen. Beispiel: IronPDF rendert HTML zu einem PDF und speichert es.

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

Hier vergleichen die relationalen Muster die Messung mit bestimmten Schwellenwerten, um ihre Klassifizierung zu bestimmen.

Der rechte Teil eines relationalen Musters muss ein Konstantenausdruck sein, der ein Ganzzahl-, Fließkomma-, char- oder enum-Typ sein kann. Die Operatoren <, >, <=, >= können auf der linken Seite verwendet werden.

Um ein Ausdrucksergebnis innerhalb eines bestimmten Bereichs abzugleichen, verwenden Sie ein konjunktives "und"-Muster, wie unten illustriert:

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

Dieser Abschnitt beschreibt, wie das konjunktive "und"-Muster genutzt wird, um die Kalenderjahreszeit basierend auf dem innerhalb bestimmter Bereiche liegenden Monat zu bestimmen. Es wird auch erwähnt, dass relationale Muster eine prägnante und ausdrucksstarke Mittel bieten, um Ausdrucksergebnisse gegen Konstanten zu vergleichen, wodurch die Codeklarheit und Wartbarkeit verbessert wird.

Muster verwerfen

Das Discard-Muster, dargestellt durch _, dient dazu, jeden Ausdruck, einschließlich null, zu erfassen. Betrachten Sie das folgende Beispiel:

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

Im oberen Discard-Musterbeispiel werden alle möglichen Eingabewerte behandelt. Alle Wochentage werden verwaltet, und ein Standardwert wird bereitgestellt. Damit werden alle möglichen Werte verarbeitet. Das Discard-Muster kann nicht als Muster in einem is-Ausdruck oder einer switch-Anweisung verwendet werden. In solchen Fällen kann ein var-Muster mit einem Discard, wie var _, verwendet werden, um jeden Ausdruck abzugleichen. Jedoch ist ein Discard-Muster in einem switch-Ausdruck zulässig. Für weitere Details beachten Sie bitte den Discard-Musterabschnitt des Feature-Vorschlags.

Logische Muster

Logische Muster in C# bieten leistungsstarke Werkzeuge zur Mustererkennung, einschließlich Negation, Konjunktion und Disjunktion, die flexiblere und ausdrucksstärkere Vergleichsbedingungen ermöglichen.

Negation (nicht Muster)

Das Negationsmuster, dargestellt durch not, erfasst einen Ausdruck, wenn das negierte Muster nicht dem Ausdruck entspricht. Dies ist besonders nützlich, um zu überprüfen, ob ein Ausdruck nicht null ist, wie unten demonstriert:

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

Hier wird der Codeblock ausgeführt, wenn input nicht null ist.

Konjunktiv (und-Muster)

Das konjunktive Muster, das das and Schlüsselwort verwendet, erfasst einen Ausdruck, wenn beide Muster dem Ausdruck entsprechen. Dies ermöglicht das Kombinieren mehrerer Bedingungen, wie im folgenden Beispiel illustriert:

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

In diesem Beispiel wird die Messung basierend auf ihrem Wertebereich klassifiziert.

Diskjunktiv (oder-Muster)

Das disjunktive Muster, das das or Schlüsselwort verwendet, erfasst einen Ausdruck, wenn eines der Muster dem Ausdruck entspricht. Dies ermöglicht das Verarbeiten mehrerer möglicher Bedingungen, wie unten gezeigt:

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

Hier wird die Kalenderjahreszeit basierend auf dem Monat des angegebenen Datums bestimmt.

Diese Musterkombinatoren können wiederholt verwendet werden, um komplexere und präzisere Vergleichsbedingungen zu erstellen, wodurch die Flexibilität und Lesbarkeit Ihres Codes verbessert wird.

Eigenschaftsmuster

Das Property-Muster ermöglicht den Vergleich der Eigenschaften oder Felder eines Ausdrucks mit verschachtelten Mustern. Ein Beispiel dafür sehen Sie im folgenden Code-Schnipsel:

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

Hier stellt das Property-Muster sicher, dass das angegebene Datum einem der angegebenen Konferenztage entspricht.

Sie können auch eine Laufzeit Typenüberprüfung und Deklaration einer Variablen innerhalb eines Property-Musters einbauen, wie unten gezeigt:

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

Hier wird das Property-Muster verwendet, um Zeichenfolgen und Zeichensammlungen zu behandeln, um eine ordnungsgemäße Handhabung basierend auf ihren Eigenschaften zu gewährleisten.

Positionsmuster

In C# ermöglicht das Positionsmuster das Zerlegen eines Ausdrucksergebnisses und den Abgleich der resultierenden Werte mit entsprechenden verschachtelten Mustern. Zum Beispiel:

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

In diesem Beispiel wird das Positionsmuster verwendet, um Punkte basierend auf ihren Koordinaten zu klassifizieren.

Darüber hinaus können Sie innerhalb eines Property-Musters auf verschachtelte Eigenschaften oder Felder verweisen, das als erweitertes Property-Muster bekannt ist, das in C# 10 eingeführt wurde:

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

Dieses Feature verbessert die Flexibilität der Property-Muster, indem es den direkten Zugriff auf verschachtelte Eigenschaften ermöglicht.

Diese Muster bieten mächtige Mechanismen zum Umgang mit komplexen Datenstrukturen und zur Verbesserung der Lesbarkeit und Ausdruckskraft Ihres Codes.

Var-Muster

Var-Muster ermöglicht es, einen beliebigen Typ abzugleichen. Dies kann besonders nützlich sein, um Zwischenresultate innerhalb von Booleschen Ausdrücken zu erfassen oder wenn in Schutzwächtern von Switch-Anweisungen mehrere Prüfungen erforderlich sind.

Hier ist ein Beispiel, das die Verwendung des Var-Musters in einem Booleschen Ausdruck demonstriert:

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

In diesem Beispiel gibt SimulateDataFetch ein Array von Ganzzahlen zurück, und das is var-Muster fängt das Ergebnis in der Variable results auf, sodass nachfolgende Berechnungen basierend auf deren Eigenschaften vorgenommen werden können.

Darüber hinaus können Var-Muster in Switch-Ausdrücken oder -Anweisungen für prägnanteren Code verwendet werden. Beispiel für die Verwendung von Var-Mustern in Switch-Fall-Schutzwächtern:

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

In diesem Beispiel fängt das Var-Muster (x, y) die Koordinaten des Punktes ein, was unterschiedliche Transformationen basierend auf ihren Werten ermöglicht.

In einem Var-Muster wird der Typ der deklarierten Variable aus dem Kompilierungszeit-Typ des Ausdrucks, der mit dem Muster abgeglichen wird, abgeleitet.

Das Var-Muster bietet eine bequeme Möglichkeit, verschiedene Szenarien zu bewältigen, in denen der spezifische Ausdruckstyp nicht im Voraus bekannt ist, und verbessert so die Codeklarheit und Flexibilität.

Einführung in die IronPDF-Bibliothek

IronPDF-Dokumenten-Rendering ist eine Bibliothek von Iron Software, die sich auf die Erstellung von PDF-Dokumenten spezialisiert hat. Um loszulegen, muss die Bibliothek zunächst aus dem NuGet-Paketmanager oder aus dem Visual Studio Paket-Manager installiert werden.

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

Das folgende Bild zeigt, wie man aus dem Visual Studio Installationshandbuch installiert.

C#-Mustererkennungsausdrücke (Wie es für Entwickler funktioniert): Abbildung 1 - Installieren von IronPDF mit dem NuGet-Paketmanager

Im nachfolgenden Code sehen wir, wie man ein einfaches PDF-Dokument erstellt:

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

Ausgabe

C#-Mustererkennungsausdrücke (Wie es für Entwickler funktioniert): Abbildung 2

Details zum Code

Hier verwenden wir die ChromePdfRenderer-Klasse von IronPDF, um den HTML-String in ein PDF-Dokument zu speichern. Das Ausgabedokument wird im Dokument "output.pdf" gespeichert.

Probelizenz

IronPDF kann mit einer Testlizenz verwendet werden, die von der IronPDF-Lizenzseite bezogen werden kann. Geben Sie eine E-Mail-Adresse an, um einen Lizenzschlüssel zu generieren, der an Ihre E-Mail-Adresse gesendet wird.

"IronPDF.LicenseKey": "<Your Key>"
"IronPDF.LicenseKey": "<Your Key>"
$vbLabelText   $csharpLabel

Platzieren Sie den Lizenzschlüssel in der appsettings.json-Datei, wie oben gezeigt.

Abschluss

Mustererkennungsausdrücke in C# bieten eine leistungsstarke und flexible Möglichkeit, bedingte Anweisungen, Typüberprüfungen und Objektdestruktionen auf prägnante und lesbare Weise zu schreiben. Durch die Nutzung der Mustererkennung können Entwickler die Klarheit und Wartbarkeit ihres Codes verbessern, während Boilerplate und Redundanz reduziert werden. Ob Typübermittlung, Switch-Anweisungen oder Destruktion, Mustererkennungsausdrücke bieten ein vielseitiges Werkzeugset zur Bewältigung einer Vielzahl von Programmieraufgaben in C#.

Abschließend kann das Meistern von Mustererkennungsausdrücken Ihre C#-Programmierfähigkeiten erheblich verbessern, sodass Sie saubereren, ausdrucksstärkeren Code schreiben können, der einfacher zu verstehen und zu pflegen ist. Wir haben auch die HTML-zu-PDF-Generierungsfähigkeiten von IronPDF behandelt, die zur Erstellung von PDF-Dokumenten genutzt werden können.

Häufig gestellte Fragen

Wie kann ich Musterabgleich verwenden, um die Lesbarkeit des Codes in C# zu verbessern?

Musterabgleich in C# ermöglicht es Entwicklern, prägnanteren und ausdrucksstärkeren Code zu schreiben, was bedingte Anweisungen klarer und leichter verständlich macht. Dies verbessert die Lesbarkeit und Wartbarkeit, indem die Komplexität von Codeblöcken reduziert wird.

Welche verschiedenen Arten von Musterabgleichsausdrücken sind in C# verfügbar?

C# unterstützt verschiedene Musterabgleichsausdrücke, einschließlich is-Ausdrücken, switch-Anweisungen und switch-Ausdrücken. Jeder Typ bietet unterschiedliche Möglichkeiten, Ausdrücke zu bewerten und Code basierend auf übereinstimmenden Mustern auszuführen.

Wie kann ich PDF-Dokumente mit C# erstellen?

Sie können IronPDF, eine Bibliothek von Iron Software, verwenden, um PDF-Dokumente in C# zu erstellen. Es ermöglicht die Umwandlung von HTML-Inhalten in PDF und ist einfach über NuGet zu installieren, mit einem breiten Spektrum an PDF-Erstellungsfunktionen.

Was sind Deklarations- und Typmuster im C#-Musterabgleich?

Deklarations- und Typmuster in C# überprüfen, ob der Laufzeittyp eines Ausdrucks einem bestimmten Typ entspricht und ermöglichen die Deklaration einer neuen lokalen Variablen, wenn eine Übereinstimmung erfolgreich ist, wodurch typsichere Operationen erleichtert werden.

Wie funktionieren Konstantenmuster in C#?

Konstantenmuster in C# werden verwendet, um zu prüfen, ob ein Ausdruck einem bestimmten konstanten Wert, wie einer Ganzzahl oder einem String, entspricht und bestimmte Logik auszuführen, wenn eine Übereinstimmung gefunden wird. Dies ermöglicht einfache Vergleiche von Konstantenwerten.

Was ist der Zweck von relationalen Mustern in C#?

Relationale Muster in C# ermöglichen es, Ausdrücke mit Konstanten unter Verwendung von relationalen Operatoren wie <, >, <= und >= zu vergleichen. Dies ist nützlich, um prägnante Bereichsüberprüfungen im Code zu implementieren.

Wie können logische Muster in C# angewendet werden?

Logische Muster in C# kombinieren andere Muster mit logischen Operatoren wie and, or und not, was komplexe Musterabgleichbedingungen ermöglicht, die mehrere Kriterien gleichzeitig auswerten können.

Was ist das Wegwerfmuster in C# und wann wird es verwendet?

Das Wegwerfmuster in C#, dargestellt durch _, stimmt mit jedem Ausdruck überein, einschließlich null, und wird häufig in Situationen verwendet, in denen bestimmte Werte ignoriert werden müssen, wie in switch-Ausdrücken.

Wie können Eigenschaftsmuster in C# verwendet werden?

Eigenschaftsmuster in C# ermöglichen es Entwicklern, die Eigenschaften oder Felder eines Objekts gegen verschachtelte Muster abzugleichen, was eine Möglichkeit bietet, tiefe Überprüfungen in der Struktur eines Objekts durchzuführen, während der Code klar und prägnant bleibt.

Jacob Mellor, Chief Technology Officer @ Team Iron
Chief Technology Officer

Jacob Mellor ist Chief Technology Officer bei Iron Software und ein visionärer Ingenieur, der führend in der C# PDF-Technologie ist. Als ursprünglicher Entwickler der Iron Software-Kerncodebasis hat er die Produktarchitektur des Unternehmens seit seiner Gründung gestaltet und zusammen mit CEO Cameron Rimington in ein Unternehmen ...

Weiterlesen