C# 中的简单图书馆目录系统






1.91/5 (9投票s)
本文描述了一个用 C# 开发的简单图书馆目录系统,可以作为基础。
引言
在本文中,我们将研究由继承和多态性实现的功能。请注意,此应用程序要求您先登录才能开始。 应用程序启动时会创建三个登录,每个用户类型一个
- 管理用户
- 登录名:admin
密码:admin - 工作人员用户
- 登录名:staff
密码:staff - 学生用户
- 登录名:student
密码:student
当程序在管理用户菜单下运行时,您可以创建更多用户。
提供的代码中使用了两个继承层次结构,一个代表不同类型的用户,另一个代表不同的目录项。
MenuBuilder 类定义了将显示给用户的每个菜单中的项目。用户管理允许创建不同的用户对象:Admin 用户、Student 用户和 Staff 用户。 逐步描述应用程序如何创建这些对象并获取其属性所需的信息。
#region Catalogue Management Menu public static void CatalogueManagementMenu(Users.User usr, out ExtendedResult result) { SortedList<string, MenuOption> menu = new SortedList<string, MenuOption>(); menu.Add("B", new MenuOption("B", "Add new book", new MenuHandler(AddBookHandler))); menu.Add("P", new MenuOption("P", "Add new periodical", new MenuHandler(AddPeriodicalHandler))); menu.Add("X", new MenuOption("X", "Exit", new MenuHandler(LogoutHandler))); result = new ExtendedResult(ResultCode.SubMenu, menu); } #endregion #region User Management Handlers private static void AddUserHandler(Users.User usr, out ExtendedResult result) { SortedList<string, MenuOption> menu = new SortedList<string, MenuOption>(); menu.Add("A", new MenuOption("A", "Administrator", new MenuHandler(AdministratorHandler))); menu.Add("M", new MenuOption("M", "Staff Member", new MenuHandler(StaffMemberHandler))); menu.Add("S", new MenuOption("S", "Student", new MenuHandler(StudentHandler))); menu.Add("X", new MenuOption("X", "Go Back", new MenuHandler(GoBackHandler))); result = new ExtendedResult(ResultCode.SubMenu, menu); }
用户的创建是通过调用 AutoPrompt.Create<>() 泛型函数完成的, <> 中指示了特定的用户(Users.Admin、Users.Staff 或 Users.Student)。
Create<>() 函数创建一个新对象(由 'datatype' 表示),然后通过引用将这个新对象传递给 CreateWorker<>() 函数,同时指示它的数据类型 (typeof(datatype))。
public static datatype Create<datatype>() where datatype : new() { datatype dt = new datatype(); CreateWorker<datatype>(ref dt, typeof(datatype)); return dt; }
CreateWorker<>() 函数
- 如果指示的数据类型是 object 类型,则立即返回,否则递归调用自身,传递相同的对象,但指示下一个祖先类类型(基类型)。因此,在传递给 CreateWorker 的类型层次结构中,实际上要处理的第一个类型是直接从 object 类型派生的数据类型,然后是下一个子类,依此类推,直到达到原始类型。
- 对于当前类型,使用一个 foreach 循环来检查每个 NonPublic(即私有或受保护)的实例成员(即非静态成员)
- 如果该类型是 Field(即属性)
- 尝试检索 AutoPrompt 代码属性,如果没有这样的代码属性,则移至循环 (b) 中标识的下一个成员。
- 检索在 AutoPrompt 代码属性中指定的提示
- 根据数据类型(大的 if/else-if 语句),提示用户输入适当的数据,然后将其存储到对象中(fi.SetValue 存储该值)。
- 如果该类型是 Field(即属性)
private static void CreateWorker<datatype>(ref datatype obj, Type t) { if (t == typeof(object)) return; CreateWorker<datatype>(ref obj, t.BaseType); foreach (MemberInfo mi in t.GetMembers(BindingFlags.NonPublic | BindingFlags.Instance)) { if (mi.MemberType == MemberTypes.Field) { AutoPrompt ap = Attribute.GetCustomAttribute(mi, typeof(AutoPrompt)) as AutoPrompt; if (ap == null) continue; FieldInfo fi = mi as FieldInfo; string fieldPrompt = ap.PromptText;
关注点
提供的代码中使用了两个继承层次结构,一个代表不同类型的用户,另一个代表不同的目录项。
历史
- 2007 年 11 月 16 日