Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
In diesem Lernprogramm erfahren Sie, wie Sie Musterabgleich verwenden, um Daten in C# zu prüfen. Sie schreiben kleine Codemengen, kompilieren und führen diesen Code aus. Das Tutorial enthält eine Reihe von Lektionen, die verschiedene Typen in C# erkunden. Diese Lektionen vermitteln Ihnen die Grundlagen der C#-Sprache.
Tipp
Wenn ein Codeausschnittblock die Schaltfläche "Ausführen" enthält, öffnet diese Schaltfläche das interaktive Fenster oder ersetzt den vorhandenen Code im interaktiven Fenster. Wenn der Codeausschnitt keine Schaltfläche "Ausführen" enthält, können Sie den Code kopieren und dem aktuellen interaktiven Fenster hinzufügen.
In den vorherigen Tutorials wurden eingebaute Typen und Typen veranschaulicht, die Sie als Tupel oder Datensätze definieren. Instanzen dieser Typen können anhand eines Musters überprüft werden. Ob eine Instanz mit einem Muster übereinstimmt, bestimmt die Aktionen, die Ihr Programm ausführt. In den folgenden Beispielen werden Sie ?
nach Typnamen feststellen. Mit diesem Symbol kann der Wert dieses Typs null sein (zum Beispiel kann bool?
true
, false
oder null
sein). Weitere Informationen finden Sie unter Nullwertetypen. Sehen wir uns an, wie Sie Muster verwenden können.
Einen Wert abgleichen
In allen Beispielen in diesem Lernprogramm werden Texteingaben verwendet, die eine Reihe von Banktransaktionen als CSV-Eingabe (Comma Separated Values) darstellen. In jedem der Beispiele können Sie den Datensatz entweder mit einem is
- oder switch
-Ausdruck mit einem Muster abgleichen. In diesem ersten Beispiel wird jede Zeile anhand des ,
Zeichens aufgeteilt, und die erste Zeichenfolge wird mithilfe eines Ausdrucks mit dem Wert "DEPOSIT" oder "WITHDRAWAL" is
. Bei Übereinstimmungen wird der Transaktionsbetrag vom aktuellen Kontostand hinzugefügt oder abgezogen. Um es arbeiten zu sehen, drücken Sie die Taste "Ausführen":
string bankRecords = """
DEPOSIT, 10000, Initial balance
DEPOSIT, 500, regular deposit
WITHDRAWAL, 1000, rent
DEPOSIT, 2000, freelance payment
WITHDRAWAL, 300, groceries
DEPOSIT, 700, gift from friend
WITHDRAWAL, 150, utility bill
DEPOSIT, 1200, tax refund
WITHDRAWAL, 500, car maintenance
DEPOSIT, 400, cashback reward
WITHDRAWAL, 250, dining out
DEPOSIT, 3000, bonus payment
WITHDRAWAL, 800, loan repayment
DEPOSIT, 600, stock dividends
WITHDRAWAL, 100, subscription fee
DEPOSIT, 1500, side hustle income
WITHDRAWAL, 200, fuel expenses
DEPOSIT, 900, refund from store
WITHDRAWAL, 350, shopping
DEPOSIT, 2500, project milestone payment
WITHDRAWAL, 400, entertainment
""";
double currentBalance = 0.0;
var reader = new StringReader(bankRecords);
string? line;
while ((line = reader.ReadLine()) is not null)
{
if (string.IsNullOrWhiteSpace(line)) continue;
// Split the line based on comma delimiter and trim each part
string[] parts = line.Split(',');
string? transactionType = parts[0]?.Trim();
if (double.TryParse(parts[1].Trim(), out double amount))
{
// Update the balance based on transaction type
if (transactionType?.ToUpper() is "DEPOSIT")
currentBalance += amount;
else if (transactionType?.ToUpper() is "WITHDRAWAL")
currentBalance -= amount;
Console.WriteLine($"{line.Trim()} => Parsed Amount: {amount}, New Balance: {currentBalance}");
}
}
Prüfen Sie die Ausgabe. Sie können sehen, dass jede Zeile verarbeitet wird, indem Sie den Wert des Texts im ersten Feld vergleichen. Das vorherige Beispiel könnte ähnlich konstruiert werden, indem der ==
Operator verwendet wird, um zu testen, ob zwei string
Werte gleich sind. Der Vergleich einer Variablen mit einer Konstante ist ein grundlegender Baustein für den Musterabgleich. Sehen wir uns mehr von den Bausteinen an, die Teil des Musterabgleichs sind.
Enum-Übereinstimmungen
Eine weitere häufige Verwendung für den Musterabgleich besteht darin, die Werte eines enum
Typs abzugleichen. In diesem nächsten Beispiel werden die Eingabedatensätze verarbeitet, um ein Tupel zu erstellen, bei dem der erste Wert ein enum
Wert ist, der eine Einzahlung oder eine Auszahlung angibt. Der zweite Wert ist der Wert der Transaktion. Um es arbeiten zu sehen, drücken Sie die Taste "Ausführen":
Warnung
Kopieren und fügen Sie nicht ein. Das interaktive Fenster muss zurückgesetzt werden, um die folgenden Beispiele auszuführen. Wenn Sie einen Fehler machen, hängt das Fenster, und Sie müssen die Seite aktualisieren, um fortzufahren.
public static class ExampleProgram
{
const string bankRecords = """
DEPOSIT, 10000, Initial balance
DEPOSIT, 500, regular deposit
WITHDRAWAL, 1000, rent
DEPOSIT, 2000, freelance payment
WITHDRAWAL, 300, groceries
DEPOSIT, 700, gift from friend
WITHDRAWAL, 150, utility bill
DEPOSIT, 1200, tax refund
WITHDRAWAL, 500, car maintenance
DEPOSIT, 400, cashback reward
WITHDRAWAL, 250, dining out
DEPOSIT, 3000, bonus payment
WITHDRAWAL, 800, loan repayment
DEPOSIT, 600, stock dividends
WITHDRAWAL, 100, subscription fee
DEPOSIT, 1500, side hustle income
WITHDRAWAL, 200, fuel expenses
DEPOSIT, 900, refund from store
WITHDRAWAL, 350, shopping
DEPOSIT, 2500, project milestone payment
WITHDRAWAL, 400, entertainment
""";
public static void Main()
{
double currentBalance = 0.0;
foreach (var transaction in TransactionRecords(bankRecords))
{
if (transaction.type == TransactionType.Deposit)
currentBalance += transaction.amount;
else if (transaction.type == TransactionType.Withdrawal)
currentBalance -= transaction.amount;
Console.WriteLine($"{transaction.type} => Parsed Amount: {transaction.amount}, New Balance: {currentBalance}");
}
}
static IEnumerable<(TransactionType type, double amount)> TransactionRecords(string inputText)
{
var reader = new StringReader(inputText);
string? line;
while ((line = reader.ReadLine()) is not null)
{
string[] parts = line.Split(',');
string? transactionType = parts[0]?.Trim();
if (double.TryParse(parts[1].Trim(), out double amount))
{
// Update the balance based on transaction type
if (transactionType?.ToUpper() is "DEPOSIT")
yield return (TransactionType.Deposit, amount);
else if (transactionType?.ToUpper() is "WITHDRAWAL")
yield return (TransactionType.Withdrawal, amount);
}
else {
yield return (TransactionType.Invalid, 0.0);
}
}
}
}
public enum TransactionType
{
Deposit,
Withdrawal,
Invalid
}
Im vorherigen Beispiel wird auch eine if
Anweisung verwendet, um den Wert eines enum
Ausdrucks zu überprüfen. Eine andere Form des Musterabgleichs verwendet einen switch
Ausdruck. Sehen wir uns diese Syntax an und wie Sie sie verwenden können.
Vollständige Übereinstimmungen mit switch
Eine Reihe von if
Anweisungen kann eine Reihe von Bedingungen testen. Der Compiler kann jedoch nicht feststellen, ob eine Reihe von if
Anweisungen erschöpfend ist oder ob spätere if
Bedingungen von früheren Bedingungen subsumiert werden. Der switch
Ausdruck stellt sicher, dass beide Merkmale erfüllt sind, was zu weniger Fehlern in Ihren Apps führt. Probieren wir es aus und experimentieren dabei. Kopieren Sie den folgenden Code. Ersetzen Sie die beiden if
Anweisungen im interaktiven Fenster durch den Ausdruck switch
, den Sie kopiert haben. Nachdem Sie den Code geändert haben, drücken Sie oben im interaktiven Fenster die Schaltfläche "Ausführen", um das neue Beispiel auszuführen.
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
(TransactionType.Withdrawal, var amount) => -amount,
_ => 0.0,
};
Wenn Sie den Code ausführen, sehen Sie, dass er gleich funktioniert. Um die Subsumption zu veranschaulichen, ordnen Sie die Schalterarme neu an, wie im folgenden Codeschnipsel gezeigt:
currentBalance += transaction switch
{
(TransactionType.Deposit, var amount) => amount,
_ => 0.0,
(TransactionType.Withdrawal, var amount) => -amount,
};
Nachdem Sie die Schalterarme neu angeordnet haben, drücken Sie die Schaltfläche "Ausführen". Der Compiler gibt einen Fehler aus, weil der Arm mit _
mit jedem Wert übereinstimmt. Daher läuft dieser letzte Arm mit TransactionType.Withdrawal
nie. Der Compiler teilt Ihnen mit, dass etwas in Ihrem Code falsch ist.
Der Compiler gibt eine Warnung aus, wenn der in einem switch
Ausdruck getestete Ausdruck Werte enthalten kann, die keinem Schalterarm entsprechen. Wenn einige Werte nicht mit einer Bedingung übereinstimmen können, ist der switch
Ausdruck nicht erschöpfend. Der Compiler gibt außerdem eine Warnung aus, wenn einige Werte der Eingabe keinem der Schalterarme entsprechen. Wenn Sie beispielsweise die Zeile mit _ => 0.0,
entfernen, stimmen ungültige Werte nicht überein. Zur Laufzeit würde dies fehlschlagen. Nachdem Sie das .NET SDK installiert und Programme in Ihrer Umgebung erstellt haben, können Sie dieses Verhalten testen. Die Onlineumgebung zeigt keine Warnungen im Ausgabefenster an.
Typmuster
Um dieses Lernprogramm abzuschließen, untersuchen wir einen weiteren Baustein zum Musterabgleich: das Typmuster. Ein Typmuster testet einen Ausdruck zur Laufzeit, um festzustellen, ob es sich um den angegebenen Typ handelt. Sie können einen Typtest entweder mit einem is
Ausdruck oder einem switch
Ausdruck verwenden. Lassen Sie uns das aktuelle Beispiel auf zwei Arten ändern. Zuerst, anstatt eines Tupels, lassen Sie uns Deposit
und Withdrawal
Datensatztypen erstellen, die die Transaktionen darstellen. Fügen Sie unten im interaktiven Fenster die folgenden Deklarationen hinzu:
public record Deposit(double Amount, string description);
public record Withdrawal(double Amount, string description);
Fügen Sie als Nächstes diese Methode nach der Main
Methode hinzu, um den Text zu analysieren und eine Reihe von Datensätzen zurückzugeben:
public static IEnumerable<object?> TransactionRecordType(string inputText)
{
var reader = new StringReader(inputText);
string? line;
while ((line = reader.ReadLine()) is not null)
{
string[] parts = line.Split(',');
string? transactionType = parts[0]?.Trim();
if (double.TryParse(parts[1].Trim(), out double amount))
{
// Update the balance based on transaction type
if (transactionType?.ToUpper() is "DEPOSIT")
yield return new Deposit(amount, parts[2]);
else if (transactionType?.ToUpper() is "WITHDRAWAL")
yield return new Withdrawal(amount, parts[2]);
}
yield return default;
}
}
Ersetzen Sie schließlich die foreach
Schleife in der Main
Methode durch den folgenden Code:
foreach (var transaction in TransactionRecordType(bankRecords))
{
currentBalance += transaction switch
{
Deposit d => d.Amount,
Withdrawal w => -w.Amount,
_ => 0.0,
};
Console.WriteLine($" {transaction} => New Balance: {currentBalance}");
}
Drücken Sie dann die Schaltfläche "Ausführen", um die Ergebnisse anzuzeigen. Diese endgültige Version testet die Eingabe anhand eines Typs.
Musterabgleich bietet ein Vokabular zum Vergleichen eines Ausdrucks mit Merkmalen. Muster können den Typ des Ausdrucks, Werte von Typen, Eigenschaftswerten und Kombinationen enthalten. Der Vergleich von Ausdrücken mit einem Muster kann deutlicher sein als mehrere if
Vergleiche. Sie haben einige der Muster untersucht, die Sie zum Abgleichen von Ausdrücken verwenden können. Es gibt viele weitere Möglichkeiten zum Verwenden des Musterabgleichs in Ihren Anwendungen. Besuchen Sie zunächst die .NET-Website , um das .NET SDK herunterzuladen, ein Projekt auf Ihrem Computer zu erstellen und den Code beizubehalten. Während Sie erkunden, erfahren Sie mehr über den Musterabgleich in C# in den folgenden Artikeln: