LINQ für die Suche
Teil des Abschnitts Objektorientierte Programmierung der C#-Journey von Coddy. Lektion 65 von 70.
Aufgabe
EinfachFügen wir deinem Bibliothekssystem mithilfe von LINQ leistungsstarke Suchfunktionen hinzu! Du implementierst Methoden, mit denen Benutzer Bücher nach verschiedenen Kriterien finden können – Suche nach Titel, Filterung nach Autor und Suche nach verfügbaren Büchern. LINQ macht diese Abfragen elegant und gut lesbar.
Du baust deine bestehende Projektstruktur weiter aus:
Book.cs: Behalte deine Book-Klasse mit den EigenschaftenId,Title,AuthorundIsAvailablesowie den MethodenBorrow()undReturn().User.cs: Behalte deine User-Klasse mit der Funktionalität zur Verfolgung von Ausleihen, einschließlichMaxBooks,CanBorrow()und den Methoden zur Verwaltung ausgeliehener Bücher.Library.cs: Hier fügst du deine von LINQ unterstützten Suchmethoden hinzu. Implementiere zusätzlich zu deiner bestehenden Ausleihlogik die folgenden Suchfunktionen:SearchByTitle(string keyword)– Gibt alle Bücher zurück, deren Titel das Schlüsselwort enthält (ohne Beachtung der Groß- und Kleinschreibung).GetBooksByAuthor(string author)– Gibt alle Bücher eines bestimmten Autors zurück (exakte Übereinstimmung, ohne Beachtung der Groß- und Kleinschreibung).GetAvailableBooks()– Gibt alle Bücher zurück, die derzeit verfügbar sind.GetBorrowedBooks()– Gibt alle Bücher zurück, die derzeit ausgeliehen sind.
Program.cs: Verarbeite Suchanfragen und zeige die Ergebnisse an.
Du erhältst die folgenden Eingaben:
- Name der Bibliothek
- Anzahl der Bücher, danach jedes Buch im Format
id|title|author - Anzahl der Ausleihvorgänge zum Einrichten des Ausgangszustands, danach jeweils ein
bookId - Ein Suchbefehl in einem der folgenden Formate:
title|keyword– Bücher nach einem Schlüsselwort im Titel durchsuchenauthor|name– Bücher nach Autor abrufenavailable– alle verfügbaren Bücher abrufenborrowed– alle ausgeliehenen Bücher abrufen
Gib für die Suchergebnisse jedes passende Buch in einer eigenen Zeile im Format {Title} by {Author} aus. Wenn keine Bücher gefunden werden, gib No books found aus. Die Ergebnisse sollten in der Reihenfolge ausgegeben werden, in der sie in der Büchersammlung der Bibliothek vorkommen.
Wenn die Eingaben beispielsweise wie folgt lauten:
City Library
5
B001|The Hobbit|Tolkien
B002|The Lord of the Rings|Tolkien
B003|1984|George Orwell
B004|Animal Farm|George Orwell
B005|The Silmarillion|Tolkien
2
B001
B003
author|TolkienDie Ausgabe sollte wie folgt aussehen:
The Hobbit by Tolkien
The Lord of the Rings by Tolkien
The Silmarillion by TolkienEin weiteres Beispiel mit derselben Bibliothekseinrichtung, diesmal mit der Suche nach verfügbaren Büchern:
City Library
5
B001|The Hobbit|Tolkien
B002|The Lord of the Rings|Tolkien
B003|1984|George Orwell
B004|Animal Farm|George Orwell
B005|The Silmarillion|Tolkien
2
B001
B003
availableDie Ausgabe sollte wie folgt aussehen:
The Lord of the Rings by Tolkien
Animal Farm by George Orwell
The Silmarillion by TolkienLINQ verwandelt komplexe Schleifen in aussagekräftige, gut lesbare Abfragen. Methoden wie Where() zum Filtern und ToList() zum Materialisieren der Ergebnisse machen deine Suchimplementierung übersichtlich und wartbar!
Probier es selbst
using System;
using System.Collections.Generic;
namespace LibrarySystem
{
class Program
{
public static void Main(string[] args)
{
// Bibliotheksnamen lesen
string libraryName = Console.ReadLine();
// Eine Library-Instanz mit dem Bibliotheksnamen erstellen
Library library = new Library(libraryName);
// Anzahl der Bücher lesen
int numBooks = Convert.ToInt32(Console.ReadLine());
// Bücher lesen und hinzufügen
for (int i = 0; i < numBooks; i++)
{
string bookInput = Console.ReadLine();
string[] bookParts = bookInput.Split('|');
string bookId = bookParts[0];
string bookTitle = bookParts[1];
string bookAuthor = bookParts[2];
Book book = new Book(bookId, bookTitle, bookAuthor);
library.AddBook(book);
}
// Anzahl der Ausleihvorgänge lesen, um den Anfangszustand festzulegen
int numBorrows = Convert.ToInt32(Console.ReadLine());
// Ausleihvorgänge verarbeiten (nur Buch-IDs)
for (int i = 0; i < numBorrows; i++)
{
string bookId = Console.ReadLine();
Book book = library.GetBookById(bookId);
if (book != null)
{
book.IsAvailable = false;
}
}
// Suchbefehl lesen
string searchCommand = Console.ReadLine();
// Suchbefehl verarbeiten
List<Book> results = new List<Book>();
if (searchCommand == "available")
{
results = library.GetAvailableBooks();
}
else if (searchCommand == "borrowed")
{
results = library.GetBorrowedBooks();
}
else if (searchCommand.Contains("|"))
{
string[] parts = searchCommand.Split('|');
string searchType = parts[0];
string searchValue = parts[1];
if (searchType == "title")
{
results = library.SearchByTitle(searchValue);
}
else if (searchType == "author")
{
results = library.GetBooksByAuthor(searchValue);
}
}
// Ergebnisse ausgeben
if (results.Count == 0)
{
Console.WriteLine("No books found");
}
else
{
foreach (Book book in results)
{
Console.WriteLine($"{book.Title} by {book.Author}");
}
}
}
}
}
Alle Lektionen in Objektorientierte Programmierung
1Grundlagen der OOP
Externe DateienNamespaces & DirektivenEinführung in Klassen & ObjekteDas 'this'-SchlüsselwortMethoden und ParameterFelder vs. EigenschaftenKonstruktorenObjektinitialisiererWiederholung – Einfacher Taschenrechner4Vererbung
Grundlegende Vererbungs-(:)-SyntaxDas „base“-Schlüsselwort„virtual“- und „override“-SchlüsselwörterVersiegelte KlassenDie „object“-BasisklasseWiederholung – Mitarbeiterhierarchie7Erweiterte Funktionen
Überladen von OperatorenIndexer (this[])ToString()-ÜberschreibungErweiterungsmethodenRückblick – Benutzerdefinierte Liste10Entwurfsmuster Teil 1
Einführung in EntwurfsmusterThread-sicheres SingletonFactory-MusterObserver-Muster (Events)Strategy-Muster13Abschließende Herausforderungen
E-Learning-PlattformKomponente für SpielfigurenFahrzeugvermietungsdienst2Eigenschaften & statische Member
Automatisch implementierte EigenschaftenNur lesbare/schreibbare EigenschaftenStatische Felder & MethodenStatische KlassenMember mit Ausdruckskörpern5Polymorphie & Interfaces
Compile- vs. Laufzeit-PolymorphieInterface vs. abstrakte KlasseMehrere InterfacesExplizite InterfacesUpcasting & DowncastingWiederholung – Formenrechner3Klassenarchitektur
Instanz- vs. statische DatenSchlüsselwörter 'readonly' & 'const'Backing FieldsRückblick – Bankkontenverwaltung6Kapselung
ZugriffsmodifikatorenEigenschaften zur KapselungImplementierung der DatenkapselungMuster für UnveränderlichkeitRückblick – Schülerdaten9Variable Argumente
Das Schlüsselwort 'params'Optionale ParameterBenannte ArgumenteMethodenüberladung12Projekt: Bibliothekssystem
ProjektstrukturBuch- und BenutzermodelleLogik des AusleihsystemsLINQ für die SucheKonsolen-UI / AdministrationsoberflächeUnit-Tests (NUnit/xUnit)Übe selbstständig: Online-C#-Compiler