Test in einer Live-Umgebung
Test in der Produktion ohne Wasserzeichen.
Funktioniert überall, wo Sie es brauchen.
Der Mustervergleich in C# ist eine leistungsstarke Funktion, die in C# 7.0 eingeführt und in den nachfolgenden Versionen erweitert wurde. Es ermöglicht Entwicklern, prägnanteren und aussagekräftigeren Code zu schreiben, wenn sie mit bedingten Anweisungen, Typüberprüfung und Dekonstruktion von Objekten arbeiten.
Mustervergleichsausdrü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 von Mustervergleichsausdrücken in C# erkunden, einschließlich Syntax, Anwendungsfälle und Codebeispiele. Am Ende des Artikels werden wir auch ein wenig über IronPDF von Iron Software um ein PDF-Dokument in C#-Anwendungen zu erzeugen.
Der Musterabgleich in C#-Code bietet eine Fülle von Vorteilen:
Der Mustervergleich wird durch die folgenden Ausdrücke unterstützt:
schaltausdrücke
Die folgenden Muster können verwendet werden, um mit den Konstrukten übereinzustimmen:
Deklarations- und Typmuster sind in C# unverzichtbare Werkzeuge, um die Kompatibilität von Laufzeitausdrücken mit vorgegebenen Typen zu prüfen. Mit Deklarationsmustern können Sie sowohl die Kompatibilität prüfen als auch gleichzeitig eine neue lokale Variable deklarieren. Betrachten Sie das folgende Beispiel:
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
Hier stellt das Deklarationsmuster sicher, dass der Ausdruck greeting, wenn er mit dem Typ string übereinstimmt, der Variablen message zugewiesen wird, was nachfolgende Operationen ermöglicht.
Wenn eine der folgenden Bedingungen zutrifft, ist das Deklarationsmuster gültig:
Es gibt eine Boxing- oder Unboxing-Konvertierung vom Laufzeittyp des Ausdrucks zum Typ T.
Betrachten Sie das folgende Beispiel, das die oben genannten Bedingungen veranschaulicht:
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
Hier passt nullableX
auf das Muster, da es sich um einen nullbaren Werttyp mit dem zugrundeliegenden Typ int handelt, und boxedy
passt, da es zu int unboxed werden kann.
Wenn Sie nur den Typ eines Ausdrucks überprüfen müssen, ohne eine neue Variable zu deklarieren, können Sie die Funktion discard _ verwenden, wie im folgenden Beispiel zu sehen:
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)),
'};
In diesem Ausschnitt dient das _ als Platzhalter für ein beliebiges typgleiches Fahrzeug.
Sowohl Deklarations- als auch Typmuster stellen sicher, dass Ausdrücke vor dem Mustervergleich nicht null sind. Sie können auf Nicht-Null prüfen, indem Sie ein negiertes Null-Konstantenmuster verwenden, wie unten dargestellt:
if (inputVal is not null)
{
// ...
}
if (inputVal is not null)
{
// ...
}
If inputVal IsNot Nothing Then
' ...
End If
Diese Negation stellt sicher, dass die Eingabe nicht Null ist, bevor weitere Operationen durchgeführt werden.
Durch die Nutzung von Deklarations- und Typmustern 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 Methode zur Handhabung typbasierter Logik und verbessern die Wartbarkeit Ihrer Codebasis.
Konstante Muster dienen dazu, zu überprüfen, ob ein Ausdrucksergebnis mit einem bestimmten konstanten Wert übereinstimmt. Betrachten Sie das folgende Beispiel:
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;
'}
Hier prüfen die Konstantenmuster, ob visitorCount
mit einem der angegebenen Konstantenwerte übereinstimmt und geben entsprechende Ticketpreise zurück.
In einem Konstantenmuster können Sie verschiedene Arten von konstanten Ausdrücken verwenden, wie z. B.:
Numerische Ganzzahl- oder Gleitkomma-Literale.
Zeichen.
String-Literale.
Boolesche Werte (richtig oder falsch).
Enum-Werte.
Der Name eines deklarierten const-Feldes oder eines Local.
null.
Ein Ausdruck vom Typ Span
Um auf Null zu prüfen, verwenden Sie ein konstantes Muster wie dieses:
if (inputVal is null)
{
return;
}
if (inputVal is null)
{
return;
}
If inputVal Is Nothing Then
Return
End If
Hier stellt das Muster sicher, dass die Eingabe Null ist, bevor weitere Operationen durchgeführt werden.
Sie können auch ein negiertes Null-Konstantenmuster verwenden, um Nicht-Null-Werte zu ermitteln:
if (inputVal is not null)
{
// ...
}
if (inputVal is not null)
{
// ...
}
If inputVal IsNot Nothing Then
' ...
End If
Dieses Muster verifiziert, dass die Eingabe nicht null ist, so dass nachfolgende Operationen sicher durchgeführt werden können.
Durch die Einbindung von Konstantenmustern in Ihren C#-Code können Sie Szenarien, in denen bestimmte Konstantenwerte abgeglichen werden müssen, effektiv handhaben und so die Klarheit und Wartbarkeit des Codes verbessern.
Relationale Muster bieten eine Möglichkeit, Ausdrucksergebnisse mit Konstanten zu vergleichen. Betrachten Sie das folgende Beispiel:
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",
'};
In diesem Fall vergleichen die relationalen Muster die Messung mit bestimmten Schwellenwerten, um ihre Klassifizierung zu bestimmen.
Der rechte Teil eines relationalen Musters muss ein konstanter Ausdruck sein, der vom Typ Ganzzahl, Gleitkomma, Char oder "enum" sein kann. Auf der linken Seite können die Operatoren <
, >
, <=,
oder >=
verwendet werden.
Um ein Ausdrucksergebnis innerhalb eines bestimmten Bereichs zu finden, verwenden Sie einen Konjunktiv und ein Muster, wie unten dargestellt:
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}."),
'};
In diesem Auszug wird beschrieben, wie das konjunktive "und"-Muster verwendet wird, um die Kalenderjahreszeit anhand der Monate zu bestimmen, die in bestimmte Bereiche fallen. Außerdem wird erwähnt, dass relationale Muster ein prägnantes und aussagekräftiges Mittel zum Vergleich von Ausdrucksergebnissen mit Konstanten darstellen und so die Klarheit und Wartbarkeit des Codes verbessern.
Das Verwerfungsmuster, bezeichnet mit _, dient der Übereinstimmung mit jedem Ausdruck, einschließlich Null. Nehmen 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,
};
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;
'}
Das obige Beispiel behandelt alle möglichen Eingabewerte. Alle Wochentage werden behandelt und stellen den Standardwert dar. Damit werden alle möglichen Werte behandelt. Das Verwerfungsmuster kann nicht als Muster in einem is-Ausdruck oder einer switch-Anweisung verwendet werden. In solchen Fällen können Sie ein var-Muster mit einem Verwerfungszeichen, wie var _, verwenden, um einen beliebigen Ausdruck zu finden. Ein Verwerfungsmuster ist jedoch in einem Switch-Ausdruck zulässig. Weitere Einzelheiten finden Sie im Abschnitt "Verwerfungsmuster" in der Notiz zum Funktionsvorschlag.
Logische Muster in C# bieten leistungsstarke Werkzeuge für den Musterabgleich, einschließlich Negation, Konjunktion und Disjunktion, die flexiblere und aussagekräftigere Abgleichbedingungen ermöglichen.
Das Negationsmuster, dargestellt durch 'not', passt auf einen Ausdruck, wenn das negierte Muster nicht auf den Ausdruck passt. Dies ist besonders nützlich, um zu prüfen, ob ein Ausdruck nicht null ist, wie unten gezeigt:
if (input is not null)
{
// ...
}
if (input is not null)
{
// ...
}
If input IsNot Nothing Then
' ...
End If
Hier wird der Codeblock ausgeführt, wenn die Eingabe nicht null ist.
Das konjunktive Muster, das das Schlüsselwort "und" verwendet, passt auf einen Ausdruck, wenn beide Muster auf den Ausdruck passen. Dies ermöglicht die Kombination mehrerer Bedingungen, wie das folgende Beispiel zeigt:
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",
'};
In diesem Beispiel wird die Messung auf der Grundlage ihres Wertebereichs klassifiziert.
Das disjunktive Muster, das das Schlüsselwort "oder" verwendet, passt auf einen Ausdruck, wenn eines der beiden Muster auf den Ausdruck passt. Auf diese Weise können mehrere mögliche Bedingungen gehandhabt werden, wie unten dargestellt:
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;
' }
Hier wird die Kalendersaison auf der Grundlage des Monats des angegebenen Datums bestimmt.
Diese Musterkombinatoren können wiederholt verwendet werden, um komplexere und präzisere Abgleichsbedingungen zu erstellen und so die Flexibilität und Lesbarkeit Ihres Codes zu verbessern.
Das Eigenschaftsmuster ermöglicht den Abgleich der Eigenschaften oder Felder eines Ausdrucks mit verschachtelten Mustern. Ein Beispiel hierfür ist im folgenden Codeausschnitt zu sehen:
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
Hier stellt das Eigenschaftsmuster sicher, dass das angegebene Datum mit einem der angegebenen Konferenztage übereinstimmt.
Sie können auch eine Laufzeittypprüfung und eine Variablendeklaration in ein Eigenschaftsmuster 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."),
};
'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."),
'};
Hier wird das Eigenschaftsmuster zur Behandlung von Zeichenketten und Zeichensammlungen verwendet, um eine ordnungsgemäße Behandlung auf der Grundlage ihrer Eigenschaften zu gewährleisten.
In C# ermöglicht das Positionsmuster die Dekonstruktion 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",
};
'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",
'};
In diesem Beispiel wird das Positionsmuster verwendet, um Punkte auf der Grundlage ihrer Koordinaten zu klassifizieren.
Außerdem können Sie auf verschachtelte Eigenschaften oder Felder innerhalb eines Eigenschaftsmusters verweisen, das als erweitertes Eigenschaftsmuster bezeichnet wird und 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 };
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
Diese Funktion erhöht die Flexibilität von Eigenschaftsmustern, indem sie den direkten Zugriff auf verschachtelte Eigenschaften ermöglicht.
Diese Muster bieten leistungsfähige Mechanismen für den Umgang mit komplexen Datenstrukturen und verbessern die Lesbarkeit und Aussagekraft Ihres Codes.
Mit Var Pattern können Sie jeden Typ abgleichen. Dies kann besonders nützlich sein, um Zwischenergebnisse in booleschen Ausdrücken zu erfassen oder wenn mehrere Prüfungen in switch case guards erforderlich sind.
Das folgende Beispiel demonstriert die Verwendung von var pattern in einem booleschen Ausdruck:
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
In diesem Beispiel gibt SimulateDataFetch
ein Array von Ganzzahlen zurück, und das is var-Muster fängt das Ergebnis in der Ergebnisvariablen ein, was nachfolgende Berechnungen auf der Grundlage ihrer Eigenschaften ermöglicht.
Außerdem können var-Muster innerhalb von switch-Ausdrücken oder -Anweisungen verwendet werden, um den Code prägnanter und lesbarer zu machen. Hier ist ein Beispiel für die Verwendung des var-Musters in switch case guards:
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
In diesem Beispiel wird das var-Muster (x, y) erfasst die Koordinaten des Punktes und ermöglicht verschiedene Transformationen auf der Grundlage ihrer Werte.
Bei einem var-Muster wird der Typ der deklarierten Variablen aus dem Kompilierzeittyp des Ausdrucks abgeleitet, der mit dem Muster verglichen wird.
Das var-Muster bietet eine bequeme Möglichkeit, mit verschiedenen Szenarien umzugehen, in denen der spezifische Typ des Ausdrucks nicht im Voraus bekannt ist, und verbessert die Klarheit und Flexibilität des Codes.
IronPDF ist eine Bibliothek von Iron Software, die sich auf die Erstellung von PDF-Dokumenten spezialisiert hat. Um loszulegen, installieren Sie die Bibliothek zunächst über den NuGet-Paketmanager oder den Visual Studio Package Manager
Install-Package IronPdf
Das folgende Bild zeigt, wie die Installation von Visual Studio.
Im folgenden Code werden wir sehen, wie wir ein einfaches PDF-Dokument erzeugen können:
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
Wir verwenden hier IronPDF chromePdfRenderer", um die HTML-Zeichenfolge im PDF-Dokument zu speichern. Die Ausgabe wird im Dokument "output.pdf" gespeichert.
IronPDF kann mit einer Testlizenz verwendet werden, die bei hier. Geben Sie eine E-Mail-ID an, um einen Lizenzschlüssel zu generieren, der Ihnen per E-Mail zugestellt wird.
"IronPDF.LicenseKey": "<Your Key>"
"IronPDF.LicenseKey": "<Your Key>"
'INSTANT VB TODO TASK: The following line uses invalid syntax:
'"IronPDF.LicenseKey": "<Your Key>"
Platzieren Sie den Lizenzschlüssel in der Datei AppSettings.Json wie oben gezeigt.
Pattern-Matching-Ausdrücke in C# bieten eine leistungsstarke und flexible Möglichkeit, bedingte Anweisungen, Typüberprüfungen und Objektdekonstruktionen in einer prägnanten und lesbaren Weise zu schreiben. Durch den Einsatz von Pattern-Matching können Entwickler die Übersichtlichkeit und Wartbarkeit ihres Codes verbessern und gleichzeitig Floskeln und Redundanzen reduzieren. Ob Typprüfung, Switch-Anweisungen oder Dekonstruktion - Mustervergleichsausdrücke bieten ein vielseitiges Toolset zur Bewältigung einer Vielzahl von Programmieraufgaben in C#.
Zusammenfassend lässt sich sagen, dass die Beherrschung von Pattern-Matching-Ausdrücken Ihre C#-Programmierkenntnisse erheblich verbessern kann und Sie in die Lage versetzt, saubereren, aussagekräftigeren Code zu schreiben, der leichter zu verstehen und zu warten ist. Auch in diesem Artikel haben wir über IronPDF die für die Erstellung von PDF-Dokumenten genutzt werden können.
9 .NET API-Produkte für Ihre Bürodokumente