案例功能要求:









实现代码:
1.DVD类: DVD实体类
namespace _01_迷你DVD管理器
{
// Model类 实体类
/*
1.私有字段
2.公有属性
3.构造方法
*/
/// <summary>
/// DVD实体类,用于封装单个DVD碟片的信息
/// 这是一个模型(Model)类,只负责数据的存储和访问
/// </summary>
public class DVD /*添加序列化*/
{
// 私有字段(Field):用于存储数据,外部无法直接访问
private string _name; // DVD的名称
private string _state; // DVD的状态("可借" 或 "已借出")
private int _date; // 借出日期(如果未借出,则为0)
private int _count; // 累计借出次数
// 公有属性(Property):提供对外的访问接口,用于安全地读写私有字段
public string Name { get { return _name; } set { _name = value; } }
public string State { get { return _state; } set { _state = value; } }
public int Date { get { return _date; } set { _date = value; } }
public int Count { get { return _count; } set { _count = value; } }
// 空参构造
public DVD() { }
/// <summary>
/// 带参数的构造函数
/// 允许在创建DVD对象时,一次性初始化所有属性
/// </summary>
/// <param name="name">DVD名称</param>
/// <param name="state">状态 ("可借" / "已借出")</param>
/// <param name="date">借出日期</param>
/// <param name="count">借出次数</param>
public DVD(string _name, string state, int date, int count)
{
this._name = _name;
this._state = state;
this._date = date;
this._count = count;
}
/// <summary>
/// 重写ToString()方法
/// 当需要将DVD对象转换为字符串时(例如打印),会返回一个包含所有属性信息的格式化字符串
/// 这对于调试和快速查看对象内容非常有用
/// </summary>
/// <returns>包含DVD所有信息的字符串</returns>
public override string ToString()
{
return $"Name:{_name},State:{_state},Date:{_date},Count:{_count}";
}
}
}
2.DVDMgr类: DVD管理器类
using System;
namespace _01_迷你DVD管理器
{
/// <summary>
/// DVD管理器类,负责所有业务逻辑的处理
/// 包括:数据初始化、菜单展示、用户输入处理、CRUD操作等
/// </summary>
public class DVDMgr
{
// 私有字段,用于存储所有DVD对象的集合
// 使用数组作为容器,容量固定为7
private DVD[] dvds = new DVD[7];
/// <summary>
/// 初始化方法,在程序启动时为DVD数组添加一些默认数据
/// </summary>
private void Init()
{
dvds[0] = new DVD("罗马假日", "已借出", 1, 15);
dvds[1] = new DVD("风声鹤唳", "可借", 0, 12);
dvds[2] = new DVD("浪漫满屋", "可借", 0, 30);
// 数组的其他位置(索引3到6)会自动初始化为null,表示空货架
}
/// <summary>
/// 新增DVD的方法
/// </summary>
/// <param name="name">要新增的DVD名称</param>
/// <returns>新增成功返回true,失败返回false</returns>
private bool Add(string name)
{
// 1. 检查是否已存在同名DVD,避免重复添加
for (int i = 0; i < dvds.Length; i++)
{
// 短路与(&&):先判断dvds[i]是否为null,不为null再比较名称
if (dvds[i] != null && dvds[i].Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine($"《{name}》已存在,无法重复添加!");
return false; // 找到重复,返回失败
}
}
// 2. 查找数组中的第一个空位(null)来存放新DVD
for (int i = 0; i < dvds.Length; i++)
{
if (dvds[i] == null)
{
// 找到了空位,创建新的DVD对象并放入数组
dvds[i] = new DVD(name, "可借", 0, 0);
return true; // 添加成功,返回true
}
}
// 3. 如果循环结束都没有找到空位,说明货架已满
return false;
}
/// <summary>
/// 打印(查看)所有DVD信息的方法
/// </summary>
private void Print()
{
// 打印表头
Console.WriteLine("序号\t状态\t名称\t\t\t借出日期\t借出次数");
Console.WriteLine("---------------------------------------------------------------------------------------");
// 遍历存储DVD的数组
for (int i = 0; i < dvds.Length; i++)
{
// 只打印非空的元素(即存在的DVD)
if (dvds[i] != null)
{
// 格式化日期显示:如果未借出(date为0),则显示空字符串
string dateStr = dvds[i].Date != 0 ? $"{dvds[i].Date}日" : "";
// 格式化名称显示:使用PadRight保证对齐,增强可读性
string nameStr = $"《{dvds[i].Name}》".PadRight(12);
// 打印单条DVD信息
Console.WriteLine($"{i + 1}\t{dvds[i].State}\t{nameStr}\t{dateStr.PadRight(8)}\t{dvds[i].Count}次");
}
}
Console.WriteLine(); // 打印一个空行,使输出更整洁
}
/// <summary>
/// 删除DVD的方法
/// </summary>
/// <param name="name">要删除的DVD名称</param>
/// <returns>删除成功返回true,失败返回false</returns>
private bool Delete(string name)
{
// 遍历数组查找要删除的DVD
for (int i = 0; i < dvds.Length; i++)
{
if (dvds[i] != null && dvds[i].Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
// 检查DVD状态,如果已借出则不允许删除
if (dvds[i].State == "已借出")
{
Console.WriteLine($"《{name}》为借出状态,不能删除!");
return false;
}
// 找到并状态合法,将该位置置为null,即实现了删除
dvds[i] = null;
return true; // 删除成功
}
}
// 遍历结束未找到,提示用户
Console.WriteLine($"没有找到《{name}》的匹配信息!");
return false;
}
/// <summary>
/// 借出DVD的方法
/// </summary>
/// <param name="name">要借出的DVD名称</param>
/// <returns>借出成功返回true,失败返回false</returns>
private bool Borrow(string name)
{
// 遍历数组查找DVD
for (int i = 0; i < dvds.Length; i++)
{
if (dvds[i] != null && dvds[i].Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
// 检查DVD是否已借出
if (dvds[i].State != "可借")
{
Console.WriteLine($"《{name}》已被借出!");
return false;
}
// 提示用户输入借出日期,并进行合法性校验
Console.WriteLine("请输入借出日期(1-31):");
if (!int.TryParse(Console.ReadLine(), out int borrowDate) || borrowDate < 1 || borrowDate > 31)
{
Console.WriteLine("借出日期无效!请输入1-31之间的整数。");
return false;
}
// 更新DVD的状态信息
dvds[i].State = "已借出"; // 状态改为已借出
dvds[i].Date = borrowDate; // 记录借出日期
dvds[i].Count++; // 借出次数加1
return true; // 借出成功
}
}
// 未找到指定DVD
Console.WriteLine($"没有找到《{name}》的匹配信息!");
return false;
}
/// <summary>
/// 归还DVD的方法
/// </summary>
/// <param name="name">要归还的DVD名称</param>
/// <returns>归还成功返回true,失败返回false</returns>
private bool ReturnDVD(string name)
{
// 遍历数组查找DVD
for (int i = 0; i < dvds.Length; i++)
{
if (dvds[i] != null && dvds[i].Name.Equals(name, StringComparison.OrdinalIgnoreCase))
{
// 检查DVD是否处于借出状态
if (dvds[i].State != "已借出")
{
Console.WriteLine($"《{name}》未被借出,无法归还!");
return false;
}
int borrowDate = dvds[i].Date; // 保存借出日期,用于计算租金
// 提示用户输入归还日期,并校验
Console.WriteLine("请输入归还日期(1-31):");
if (!int.TryParse(Console.ReadLine(), out int returnDate) || returnDate < 1 || returnDate > 31)
{
Console.WriteLine("归还日期无效!请输入1-31之间的整数。");
return false;
}
// 确保归还日期不早于借出日期
if (returnDate < borrowDate)
{
Console.WriteLine("归还日期不能小于借出日期,请重新操作!");
return false;
}
// 计算租金(假设每天租金为1元)
int rent = returnDate - borrowDate;
// 更新DVD状态
dvds[i].State = "可借"; // 状态改回可借
dvds[i].Date = 0; // 清空借出日期
// 输出归还成功信息及费用
Console.WriteLine($"归还《{name}》成功!");
Console.WriteLine($"借出日期:{borrowDate}日");
Console.WriteLine($"归还日期:{returnDate}日");
Console.WriteLine($"应付租金:{rent}元");
return true;
}
}
// 未找到指定DVD
Console.WriteLine($"没有找到《{name}》的匹配信息!");
return false;
}
/// <summary>
/// 菜单切换和用户交互的主方法
/// 这是一个无限循环,直到用户选择退出
/// </summary>
public void ChangeMenu()
{
Init(); // 在菜单显示前,先初始化默认数据
// 使用do-while循环,确保菜单至少显示一次
do
{
// 清空控制台,提供一个干净的界面(在某些环境下可能需要)
// Console.Clear();
// 打印菜单标题和选项
Console.WriteLine("\n欢迎使用迷你DVD管理器");
Console.WriteLine("--------------------------");
Console.WriteLine("1.新增DVD");
Console.WriteLine("2.查看DVD");
Console.WriteLine("3.删除DVD");
Console.WriteLine("4.借出DVD");
Console.WriteLine("5.归还DVD");
Console.WriteLine("6.退出DVD");
Console.WriteLine("--------------------------");
Console.Write("请选择(1-6):"); // 使用Write而不是WriteLine,让光标紧跟在提示后
// 处理用户输入,使用int.TryParse防止因输入非数字字符而导致程序崩溃
string input = Console.ReadLine();
if (!int.TryParse(input, out int selectNumber) || selectNumber < 1 || selectNumber > 6)
{
Console.WriteLine("\n输入无效!请输入1到6之间的整数。");
Console.WriteLine("按任意键继续...");
Console.ReadKey();
continue; // 跳过本次循环的剩余部分,直接开始下一次循环(重新显示菜单)
}
// 根据用户的选择,使用switch-case执行不同的操作
switch (selectNumber)
{
case 1:
Console.WriteLine("\n---> 新增DVD");
Console.Write("请输入DVD名称:");
string addName = Console.ReadLine()?.Trim() ?? string.Empty;
if (string.IsNullOrEmpty(addName))
{
Console.WriteLine("DVD名称不能为空!");
break;
}
bool addResult = Add(addName);
Console.WriteLine(addResult ? $"新增《{addName}》成功!" : $"新增《{addName}》失败!货架已满或名称重复。");
break;
case 2:
Console.WriteLine("\n---> 查看DVD");
Print(); // 调用打印方法
break;
case 3:
Console.WriteLine("\n---> 删除DVD");
Console.Write("请输入要删除的DVD名称:");
string delName = Console.ReadLine()?.Trim() ?? string.Empty;
if (string.IsNullOrEmpty(delName))
{
Console.WriteLine("DVD名称不能为空!");
break;
}
bool delResult = Delete(delName);
if (delResult) Console.WriteLine($"删除《{delName}》成功!");
break;
case 4:
Console.WriteLine("\n---> 借出DVD");
Console.Write("请输入要借出的DVD名称:");
string borrowName = Console.ReadLine()?.Trim() ?? string.Empty;
if (string.IsNullOrEmpty(borrowName))
{
Console.WriteLine("DVD名称不能为空!");
break;
}
bool borrowResult = Borrow(borrowName);
if (borrowResult) Console.WriteLine($"借出《{borrowName}》成功!");
break;
case 5:
Console.WriteLine("\n---> 归还DVD");
Console.Write("请输入要归还的DVD名称:");
string returnName = Console.ReadLine()?.Trim() ?? string.Empty;
if (string.IsNullOrEmpty(returnName))
{
Console.WriteLine("DVD名称不能为空!");
break;
}
ReturnDVD(returnName); // 返回操作的成功信息在其内部已打印
break;
case 6:
Console.WriteLine("\n谢谢使用,再见!");
return; // 退出当前方法,从而结束程序
default:
Console.WriteLine("\n无效的选择,请重新输入。");
break;
}
// 在每次操作后暂停,让用户看清结果,按任意键后返回菜单
Console.WriteLine("\n按任意键返回菜单...");
Console.ReadKey();
} while (true); // 循环条件永远为true,除非用户选择case 6退出
}
}
}
3.Program类: 主程序类
/*
Model类 实体类---就是程序当中你的操作对象(DVD)
DVD类--->DVDMgr类
*/
namespace _01_迷你DVD管理器
{
internal class Program
{
static void Main(string[] args)
{
// 创建DVD管理器的实例
DVDMgr dVDMgr = new DVDMgr();
// 调用管理器的菜单方法
dVDMgr.ChangeMenu();
}
}
}
希望对大家有所帮助。感谢大家的关注和点赞。
36

被折叠的 条评论
为什么被折叠?



