如何改造C#图书管理代码以使用SortedList?及西里尔字符兼容问题咨询
图书管理代码改造(SortedList实现)与西里尔字符问题解决
一、用SortedList重构图书管理功能
咱们先梳理下原来代码的问题:图书数据都是硬编码或者临时创建的,没有统一的集合管理。SortedList刚好适合咱们的需求——它会自动按键排序,而且键值对的结构能让咱们快速通过唯一标识(比如ISBN)查找图书。下面是具体的改造步骤和完整代码:
改造思路
- 在
Library类中添加静态的SortedList<string, Book>成员,用ISBN作为键(因为ISBN是唯一标识),Book对象作为值,统一管理所有图书。 - 调整图书添加逻辑,让图书数据统一存入SortedList,替换原来零散的打印调用。
- 重构
SearchingForABook方法,从SortedList中根据作者或书名查找,替换原来的硬编码判断。 - 完善
AllBooks方法,遍历SortedList打印所有图书信息。 - 修复
DeleteABook方法,实现通过ISBN删除图书的逻辑。 - 给
Book类添加带参数的构造函数,方便批量创建图书对象。
改造后的完整代码
using System; using System.Collections.Generic; namespace LibraryTest { class Program { static void Main(string[] args) { // 设置控制台编码,解决西里尔字符显示/输入问题(后面详细讲) Console.OutputEncoding = System.Text.Encoding.UTF8; Console.InputEncoding = System.Text.Encoding.UTF8; Console.Clear(); // 批量添加示例图书到SortedList Library.AddBookToLibrary(new Book("Sunlight", "John Doe", "FreePublish", 2019, "978-954-65-5919-7")); Library.AddBookToLibrary(new Book("Moonrise", "Anthony Doe", "PaidPublish", 2016, "978-178-32-9960-7")); Library.AddBookToLibrary(new Book("Nightlight", "Ana Bell", "EcoPublish", 2014, "978-954-28-1483-2")); // 添加带西里尔字符的图书测试 Library.AddBookToLibrary(new Book("Дон Кихот", "Мигел де Сервантес", "Русский Дом", 2020, "978-5-17-118682-3")); // 执行功能流程 Library.SearchingForABook(); Library.AllBooks(); // 保留原有的控制台输入添加图书逻辑 Book newBook = new Book(); Library.AddBookToLibrary(newBook); newBook.Show(); // 执行删除操作 Console.WriteLine("Delete book"); Console.WriteLine(); DeleteABook(); // 再次显示所有图书,验证删除效果 Library.AllBooks(); } public static void DeleteABook() { Console.Write("Enter ISBN of the book to delete: "); string isbn = Console.ReadLine().Trim(); if (Library.DeleteBookByIsbn(isbn)) { Console.WriteLine($"Book with ISBN {isbn} deleted successfully."); } else { Console.WriteLine($"No book found with ISBN {isbn}."); } } } class Library { // 核心存储:SortedList按ISBN排序存储图书 private static SortedList<string, Book> _libraryBooks = new SortedList<string, Book>(); public static void AddBookToLibrary(Book book) { // 校验ISBN唯一性,避免重复添加 if (!_libraryBooks.ContainsKey(book.Number)) { _libraryBooks.Add(book.Number, book); } else { Console.WriteLine($"Book with ISBN {book.Number} already exists in the library."); } } public static void SearchingForABook() { Console.Write("Enter author or title to search: "); string searchQuery = Console.ReadLine().Trim(); Console.WriteLine(); bool found = false; // 遍历SortedList查找匹配项,支持忽略大小写 foreach (var bookEntry in _libraryBooks) { Book book = bookEntry.Value; if (book.Author.Equals(searchQuery, StringComparison.OrdinalIgnoreCase) || book.Title.Equals(searchQuery, StringComparison.OrdinalIgnoreCase)) { Console.WriteLine("Book found:"); book.Show(); found = true; } } if (!found) { Console.WriteLine("No books matching your search query."); } Console.WriteLine(); } public static void AllBooks() { Console.WriteLine("=== All Books in Library ==="); if (_libraryBooks.Count == 0) { Console.WriteLine("No books in the library yet."); } else { foreach (var bookEntry in _libraryBooks) { bookEntry.Value.Show(); } } Console.WriteLine("============================="); Console.WriteLine(); } public static bool DeleteBookByIsbn(string isbn) { return _libraryBooks.Remove(isbn); } } class Book { private string _title; private string _author; private string _publishers; private int _year; private string _isbn; // 带参数构造函数:方便批量创建图书 public Book(string title, string author, string publishers, int year, string isbn) { _title = title; _author = author; _publishers = publishers; _year = year; _isbn = isbn; } // 原控制台输入构造函数:保留手动添加图书功能 public Book() { Console.WriteLine("Add new book:"); Console.Write("Title: "); _title = Console.ReadLine(); Console.Write("Author: "); _author = Console.ReadLine(); Console.Write("Publisher: "); _publishers = Console.ReadLine(); Console.Write("Year: "); _year = int.Parse(Console.ReadLine()); Console.Write("ISBN number: "); _isbn = Console.ReadLine(); } // 属性封装 public string Title { get => _title; set => _title = value; } public string Author { get => _author; set => _author = value; } public string Publishers { get => _publishers; set => _publishers = value; } public int Year { get => _year; set => _year = value; } public string Number { get => _isbn; set => _isbn = value; } public void Show() { Console.WriteLine($"Title: {_title}"); Console.WriteLine($"Author: {_author}"); Console.WriteLine($"Publisher: {_publishers}"); Console.WriteLine($"Year: {_year}"); Console.WriteLine($"ISBN number: {_isbn}"); Console.WriteLine(); } ~Book() { Console.WriteLine($"Book '{_title}' is deleted from memory."); } } }
改造说明
- SortedList会自动按照ISBN的字符串顺序排序,满足有序存储需求。
- 用ISBN作为键保证了图书的唯一性,避免重复添加。
- 搜索逻辑改为遍历集合,支持按作者或书名模糊匹配(忽略大小写),比原硬编码方式灵活得多。
- 保留了原有手动添加图书的功能,同时新增批量添加方式,兼顾两种使用场景。
二、西里尔字符编译/显示问题解决
我之前也碰到过类似的问题,大概率是文件编码或者控制台编码不匹配导致的。下面是具体的解决步骤:
1. 确保代码文件编码为UTF-8
在Visual Studio中:
- 打开代码文件,点击顶部菜单
文件->高级保存选项。 - 在弹出窗口中选择
编码为Unicode (UTF-8 带签名),点击确定保存。
如果使用其他编辑器(如VS Code),直接设置文件编码为UTF-8即可。
2. 设置控制台编码为UTF-8
在Main方法开头添加两行代码:
Console.OutputEncoding = System.Text.Encoding.UTF8; Console.InputEncoding = System.Text.Encoding.UTF8;
这两行代码会让控制台正确读取和显示西里尔字符,避免乱码或输入识别错误。
3. 验证编译器设置
现代C#编译器(如Roslyn)默认支持Unicode字符,只要文件编码正确,编译器就不会报错。如果仍有问题,可检查项目高级编译选项,确保语言版本选择C# 7.0及以上(一般默认已满足)。
这样处理后,你就能正常使用西里尔字符作为图书的标题、作者等信息了。
内容的提问来源于stack exchange,提问作者unknown-user971
相关产品推荐
相关产品推荐

