C#图书馆管理系统boklista搜索及Main方法位置问题咨询
图书馆管理系统问题解答
问题1:如何在图书列表(boklista)中按指定关键词搜索
你当前写的SearchBook()方法存在逻辑偏差:方法中匹配的是bok.Text()返回的馆藏位置提示文本(比如Found in section B),而非用户实际会搜索的书名、作者、图书类型字段,会导致用户输入书名/作者时完全搜不到结果。
正确的实现逻辑如下:
- 保留大小写不敏感匹配的思路,将搜索关键词和待匹配字段统一转为小写后比对,避免大小写导致匹配失败
- 匹配字段覆盖图书核心属性:书名
BookNamn、作者Author、图书类型BookType - 匹配到结果后不要直接终止遍历,要输出匹配到的完整图书信息,方便用户查看
- 增加空值判断,避免字段为空时触发异常
修正后的SearchBook()方法参考:
public static void SearchBook() { string searchKeyword; List<Book> matchedBooks = new List<Book>(); // 校验搜索关键词非空 do { Console.Write("\n\n\t\t请输入搜索关键词:"); searchKeyword = Console.ReadLine()?.Trim(); if (string.IsNullOrEmpty(searchKeyword)) { Console.WriteLine("\n\n\t\t搜索关键词不能为空,请重新输入!\n"); } } while (string.IsNullOrEmpty(searchKeyword)); string lowerKeyword = searchKeyword.ToLower(); // 遍历匹配所有符合条件的图书 foreach (var book in bookList) { bool isMatch = (book.BookNamn?.ToLower().Contains(lowerKeyword) ?? false) || (book.Author?.ToLower().Contains(lowerKeyword) ?? false) || (book.BookType?.ToLower().Contains(lowerKeyword) ?? false); if (isMatch) { matchedBooks.Add(book); } } // 输出结果 if (matchedBooks.Count == 0) { Console.WriteLine($"\n\n\t\t未找到和关键词「{searchKeyword}」匹配的图书。"); return; } Console.WriteLine($"\n\n\t\t共找到{matchedBooks.Count}本匹配的图书:"); foreach (var book in matchedBooks) { Console.WriteLine(book.ToString()); Console.WriteLine(book.Text() + "\n"); } }
问题2:Main方法放在静态Librarian类中是否不合理,是否需要拆分
- 从C#语法规则来说,静态类中放置
Main方法作为程序入口是完全合法的,对于小型演示项目来说这种写法没有问题,可以正常运行。 - 但从你要求实现封装、多态的设计目标,以及后续代码可维护性的角度来说,建议拆分,原因如下:
- 不符合单一职责原则:
Librarian(图书管理员)类的核心职责是封装图书列表、处理图书新增/查询/遍历等业务逻辑;而Main方法的作用是程序启动、渲染交互菜单、处理用户输入的流程控制,二者职责边界完全不同,混写在一起后续功能迭代(比如新增借书/还书、用户权限管理功能)时,类的代码会快速膨胀变得难以维护。 - 不利于业务逻辑复用:如果后续你需要给这个系统加图形界面、或者提供API接口,把入口逻辑和业务逻辑拆分后,可以直接复用
Librarian类里的所有图书操作方法,不需要重复写业务代码。
- 不符合单一职责原则:
- 拆分方式非常简单,不会破坏你现有的封装设计:
- 新建一个
Program类,把Main方法完整挪到这个类里作为程序唯一入口 Librarian类保留为封装图书业务的类,bookList依旧保持private访问权限,对外只暴露需要的操作方法,完全符合封装要求。
- 新建一个
附:原始提交代码
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace bibliotekarie { public class Book { public string BookNamn; public string Author; public string BookType; public Book(string _BookNamn, String _Author, string _BookType) { BookNamn = _BookNamn; Author = _Author; BookType = _BookType; } public override string ToString() { return "\n\t\t" + BookNamn + " (" + BookType + ")" + "\n\t\tby " + Author; } public virtual string Text() { return "\t\tFound in section A."; } } public class Novel : Book { public Novel(string _BookNamn, String _Author, string _BookType) : base(_BookNamn, _Author, _BookType) { this.BookType = "Novel"; } public override string Text() { return "\t\tFound in section B."; } } public class ShortStory : Book { public ShortStory(string _BookNamn, String _Author, string _BookType) : base(_BookNamn, _Author, _BookType) { this.BookType = "ShortStory"; } public override string Text() { return "\t\tFound in section C."; } } public class Journal : Book { public Journal(string _BookNamn, String _Author, string _BookType) : base(_BookNamn, _Author, _BookType) { this.BookType = "Journal"; } public override string Text() { return "\t\tFound in section D."; } } static class Librarian { private static List<Book> bookList = new List<Book>(); public static void GetBookList() { foreach (Book item in bookList) { Console.WriteLine(item.ToString() + "\n"); Console.WriteLine(item.Text() + "\n"); } } public static void CreateBook() { string name = ""; string author = ""; while (name.Length == 0) { Console.Write("\n\n\t\tStart by entering the name of the book. Please enter the name: "); name = Console.ReadLine(); } while (author.Length == 0) { Console.Write("\n\n\t\tWho is the author of the book?: "); author = Console.ReadLine(); } Console.Write("\n\n\t\tPlease specify the book type: [1] Novel, [2] Journal, or [3] Short story?: "); int nyVal; int.TryParse(Console.ReadLine(), out nyVal); switch (nyVal) { case 1: { Book newBok = new Novel(name, author, "(Novel)"); bookList.Add(newBok); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("\n\n\t\tSaved!"); Console.ResetColor(); break; } case 2: { Book newBok = new Journal(name, author, "(Journal)"); bookList.Add(newBok); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("\n\n\t\tSaved!"); Console.ResetColor(); break; } case 3: { Book newBok = new ShortStory(name, author, "(Short story)"); bookList.Add(newBok); Console.ForegroundColor = ConsoleColor.Yellow; Console.WriteLine("\n\n\t\tSaved!"); Console.ResetColor(); break; } default: { Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\n\n\t\tNågonting gick fel. Det gick inte att spara. Testa igen."); Console.ResetColor(); break; } } } public static void SearchBook() { string searchItems; bool found = false; do { Console.Write("\n\n\t\tSearch the library: "); searchItems = Console.ReadLine(); if (searchItems == "") { Console.WriteLine("\n\n\t\tThe search field cannot be empty. Try again!\n"); } } while (searchItems == ""); // this is what I added // for each bok in list foreach (var bok in bookList) { // if bok text matches searchItems //if(bok.Text() == searchItems) { // commented out exact match, to get similar matches using Contains if (bok.Text().ToLower().Contains(searchItems.ToLower())) { found = true; break; } } if (found) { Console.WriteLine("\n\n\t\t" + searchItems + " was found."); } else { Console.WriteLine("\n\n\t\t" + searchItems + " was not found."); } } static void Main(string[] args) { bookList.Add(new Book("Book1", "Author1", "Book")); bookList.Add(new Novel("Book2", "Author2", "Novel")); bookList.Add(new Journal("Book3", "Author3", "Journal")); bookList.Add(new ShortStory("Book4", "Author4", "Short Story")); bool isRunning = true; while (isRunning) { Console.Write("\n\n\t\tWelcome to the library!\n"); Console.WriteLine("\n\n\t\t[1] Register a new book"); Console.WriteLine("\n\n\t\t[2] View a list of the books"); Console.WriteLine("\n\n\t\t[3] Search through the library database"); Console.WriteLine("\n\n\t\t[4] End program"); Console.Write("\n\n\t\tChoose: "); int Choice; Int32.TryParse(Console.ReadLine(), out Choice); switch (Choice) { case 1: CreateBook(); break; case 2: GetBookList(); Console.ReadLine(); break; case 3: SearchBook(); break; case 4: Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("\n\n\t\tThis program will now close."); Thread.Sleep(1500); Console.ResetColor(); isRunning = false; break; default: Console.WriteLine("\n\n\t\tAn error occurred, but you can try again."); break; } } } } }
内容的提问来源于stack exchange,提问作者uuresearcher
相关产品推荐
相关产品推荐

