项目3 - 学生信息管理系统
嗨,朋友!我是长安。
完成了待办事项管理,这次我们要做一个完整的学生信息管理系统,学习更复杂的数据管理、LINQ 查询和统计功能。这个项目会让你深入理解面向对象编程和数据库的 CRUD 操作思想。
🎯 项目目标
通过这个项目,你将:
- 掌握完整的 CRUD(增删改查)操作
- 学会使用 LINQ 进行复杂的数据查询和统计
- 理解数据验证的重要性
- 学会设计合理的类结构
- 实现更复杂的业务逻辑
📁 项目结构
StudentManagement/
├── Program.cs # 主程序
├── Student.cs # 学生类
├── StudentManager.cs # 学生管理类
└── students.json # 数据存储文件
🎯 项目需求
功能列表
- 添加学生 - 输入学号、姓名、年龄、成绩
- 查询学生 - 按学号或姓名查询
- 修改学生信息 - 修改学生的各项信息
- 删除学生 - 按学号删除
- 显示所有学生 - 列表显示,支持排序
- 统计信息 - 平均分、最高分、最低分、及格率等
- 数据持久化 - JSON 格式保存和加载
运行效果
===== 学生信息管理系统 =====
1. 添加学生
2. 查询学生
3. 修改学生信息
4. 删除学生
5. 显示所有学生
6. 统计信息
7. 保存并退出
请选择操作: 1
--- 添加学生 ---
请输入学号: 2024001
请输入姓名: 张三
请输入年龄: 20
请输入成绩: 85.5
✓ 添加成功!
请选择操作: 5
===== 学生列表 =====
学号 姓名 年龄 成绩
---------------------------
2024001 张三 20 85.5
---------------------------
共 1 名学生
🤔 需求分析
在开始编码之前,让我们分析一下需求:
数据管理
- 学生信息包括:学号(唯一)、姓名、年龄、成绩
- 需要支持增删改查操作
- 学号必须唯一,不能重复
查询功能
- 按学号精确查询
- 按姓名模糊查询
- 支持多种排序方式
统计功能
- 计算平均分
- 找出最高分和最低分
- 计算及格率(60分及以上)
- 按分数段统计
数据验证
- 学号不能为空且不能重复
- 姓名不能为空
- 年龄必须在合理范围内(如15-30)
- 成绩必须在0-100之间
📐 功能设计
1. 程序流程图
开始
↓
从文件加载学生数据
↓
┌─────────────────┐
│ 显示主菜单 │←────┐
└─────────────────┘ │
↓ │
获取用户选择 │
↓ │
┌─────────────────┐ │
│ 1. 添加学生 │─────┤
│ 2. 查询学生 │─────┤
│ 3. 修改信息 │─────┤
│ 4. 删除学生 │─────┤
│ 5. 显示所有 │─────┤
│ 6. 统计信息 │─────┤
│ 7. 保存退出 │─────┘
└─────────────────┘
↓
保存数据到文件
↓
结束
2. 类设计
Student 类 - 学生实体类
属性:
- StudentId: string (学号)
- Name: string (姓名)
- Age: int (年龄)
- Score: double (成绩)
方法:
- ToString() (显示学生信息)
- Validate() (验证数据有效性)
StudentManager 类 - 学生管理类
属性:
- students: List<Student> (学生列表)
- filePath: string (数据文件路径)
方法:
- AddStudent() (添加学生)
- GetStudent() (查询学生)
- UpdateStudent() (修改学生)
- DeleteStudent() (删除学生)
- GetAllStudents() (获取所有学生)
- GetStatistics() (获取统计信息)
- SaveToFile() (保存到文件)
- LoadFromFile() (从文件加载)
💻 代码实现
第一步:项目初始化
# 创建新的控制台项目
mkdir StudentManagement
cd StudentManagement
dotnet new console
# 添加 JSON 序列化支持(如果使用 .NET 6+,已内置)
第二步:定义 Student 类
创建 Student.cs 文件:
using System;
using System.Text.Json.Serialization;
namespace StudentManagement
{
/// <summary>
/// 学生实体类
/// </summary>
public class Student
{
/// <summary>
/// 学号(唯一标识)
/// </summary>
[JsonPropertyName("studentId")]
public string StudentId { get; set; }
/// <summary>
/// 姓名
/// </summary>
[JsonPropertyName("name")]
public string Name { get; set; }
/// <summary>
/// 年龄
/// </summary>
[JsonPropertyName("age")]
public int Age { get; set; }
/// <summary>
/// 成绩
/// </summary>
[JsonPropertyName("score")]
public double Score { get; set; }
/// <summary>
/// 构造函数
/// </summary>
public Student()
{
}
public Student(string studentId, string name, int age, double score)
{
StudentId = studentId;
Name = name;
Age = age;
Score = score;
}
/// <summary>
/// 验证学生数据是否有效
/// </summary>
public bool Validate(out string errorMessage)
{
if (string.IsNullOrWhiteSpace(StudentId))
{
errorMessage = "学号不能为空!";
return false;
}
if (string.IsNullOrWhiteSpace(Name))
{
errorMessage = "姓名不能为空!";
return false;
}
if (Age < 15 || Age > 30)
{
errorMessage = "年龄必须在15-30之间!";
return false;
}
if (Score < 0 || Score > 100)
{
errorMessage = "成绩必须在0-100之间!";
return false;
}
errorMessage = string.Empty;
return true;
}
/// <summary>
/// 判断是否及格
/// </summary>
public bool IsPassed()
{
return Score >= 60;
}
/// <summary>
/// 获取成绩等级
/// </summary>
public string GetGrade()
{
if (Score >= 90) return "优秀";
if (Score >= 80) return "良好";
if (Score >= 70) return "中等";
if (Score >= 60) return "及格";
return "不及格";
}
/// <summary>
/// 重写ToString方法
/// </summary>
public override string ToString()
{
return $"{StudentId,-12}{Name,-10}{Age,-6}{Score,-8:F1}{GetGrade()}";
}
}
}
代码讲解:
[JsonPropertyName]:用于 JSON 序列化时指定属性名Validate():集中验证所有数据,返回是否有效及错误信息IsPassed():判断是否及格(≥60分)GetGrade():根据分数返回等级ToString():格式化输出学生信息,用于显示{StudentId,-12}:左对齐,占12个字符宽度
第三步:实现 StudentManager 类
创建 StudentManager.cs 文件:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Json;
namespace StudentManagement
{
/// <summary>
/// 学生管理类
/// </summary>
public class StudentManager
{
private List<Student> students; // 学生列表
private readonly string filePath; // 数据文件路径
/// <summary>
/// 构造函数
/// </summary>
public StudentManager(string filePath = "students.json")
{
this.filePath = filePath;
students = new List<Student>();
LoadFromFile();
}
/// <summary>
/// 添加学生
/// </summary>
public bool AddStudent(Student student)
{
// 验证数据
if (!student.Validate(out string errorMessage))
{
Console.WriteLine($"✗ {errorMessage}");
return false;
}
// 检查学号是否已存在
if (students.Any(s => s.StudentId == student.StudentId))
{
Console.WriteLine($"✗ 学号 {student.StudentId} 已存在!");
return false;
}
students.Add(student);
Console.WriteLine("✓ 添加成功!");
return true;
}
/// <summary>
/// 按学号查询学生
/// </summary>
public Student GetStudentById(string studentId)
{
return students.FirstOrDefault(s => s.StudentId == studentId);
}
/// <summary>
/// 按姓名模糊查询学生
/// </summary>
public List<Student> GetStudentsByName(string name)
{
return students.Where(s => s.Name.Contains(name)).ToList();
}
/// <summary>
/// 获取所有学生
/// </summary>
public List<Student> GetAllStudents()
{
return students;
}
/// <summary>
/// 修改学生信息
/// </summary>
public bool UpdateStudent(string studentId, Student updatedStudent)
{
var student = GetStudentById(studentId);
if (student == null)
{
Console.WriteLine("✗ 找不到该学生!");
return false;
}
// 验证新数据
if (!updatedStudent.Validate(out string errorMessage))
{
Console.WriteLine($"✗ {errorMessage}");
return false;
}
// 如果修改了学号,检查新学号是否已存在
if (updatedStudent.StudentId != studentId &&
students.Any(s => s.StudentId == updatedStudent.StudentId))
{
Console.WriteLine($"✗ 学号 {updatedStudent.StudentId} 已存在!");
return false;
}
// 更新数据
student.StudentId = updatedStudent.StudentId;
student.Name = updatedStudent.Name;
student.Age = updatedStudent.Age;
student.Score = updatedStudent.Score;
Console.WriteLine("✓ 修改成功!");
return true;
}
/// <summary>
/// 删除学生
/// </summary>
public bool DeleteStudent(string studentId)
{
var student = GetStudentById(studentId);
if (student == null)
{
Console.WriteLine("✗ 找不到该学生!");
return false;
}
students.Remove(student);
Console.WriteLine("✓ 删除成功!");
return true;
}
/// <summary>
/// 显示所有学生
/// </summary>
public void DisplayAllStudents(string sortBy = "id")
{
Console.WriteLine("\n===== 学生列表 =====");
if (students.Count == 0)
{
Console.WriteLine("暂无学生信息");
Console.WriteLine("====================");
return;
}
// 排序
var sortedStudents = sortBy.ToLower() switch
{
"name" => students.OrderBy(s => s.Name).ToList(),
"age" => students.OrderBy(s => s.Age).ToList(),
"score" => students.OrderByDescending(s => s.Score).ToList(),
_ => students.OrderBy(s => s.StudentId).ToList()
};
// 显示表头
Console.WriteLine($"{'学号',-12}{'姓名',-10}{'年龄',-6}{'成绩',-8}等级");
Console.WriteLine(new string('-', 50));
// 显示每个学生
foreach (var student in sortedStudents)
{
Console.WriteLine(student);
}
Console.WriteLine(new string('-', 50));
Console.WriteLine($"共 {students.Count} 名学生");
}
/// <summary>
/// 获取统计信息
/// </summary>
public void ShowStatistics()
{
Console.WriteLine("\n===== 统计信息 =====");
if (students.Count == 0)
{
Console.WriteLine("暂无数据");
Console.WriteLine("====================");
return;
}
// 基本统计
int totalCount = students.Count;
double avgScore = students.Average(s => s.Score);
double maxScore = students.Max(s => s.Score);
double minScore = students.Min(s => s.Score);
int passedCount = students.Count(s => s.IsPassed());
double passRate = (double)passedCount / totalCount * 100;
Console.WriteLine($"总人数: {totalCount}");
Console.WriteLine($"平均分: {avgScore:F2}");
Console.WriteLine($"最高分: {maxScore:F1}");
Console.WriteLine($"最低分: {minScore:F1}");
Console.WriteLine($"及格人数: {passedCount}");
Console.WriteLine($"及格率: {passRate:F1}%");
// 分数段统计
Console.WriteLine("\n分数段分布:");
var groups = new Dictionary<string, int>
{
["优秀(90-100)"] = students.Count(s => s.Score >= 90),
["良好(80-89)"] = students.Count(s => s.Score >= 80 && s.Score < 90),
["中等(70-79)"] = students.Count(s => s.Score >= 70 && s.Score < 80),
["及格(60-69)"] = students.Count(s => s.Score >= 60 && s.Score < 70),
["不及格(0-59)"] = students.Count(s => s.Score < 60)
};
foreach (var group in groups)
{
double percentage = (double)group.Value / totalCount * 100;
Console.WriteLine($" {group.Key}: {group.Value} 人 ({percentage:F1}%)");
}
// 最高分和最低分的学生
var topStudent = students.First(s => s.Score == maxScore);
var bottomStudent = students.First(s => s.Score == minScore);
Console.WriteLine($"\n最高分学生: {topStudent.Name} ({topStudent.StudentId}) - {maxScore:F1}分");
Console.WriteLine($"最低分学生: {bottomStudent.Name} ({bottomStudent.StudentId}) - {minScore:F1}分");
Console.WriteLine("====================");
}
/// <summary>
/// 保存到文件
/// </summary>
public void SaveToFile()
{
try
{
var options = new JsonSerializerOptions
{
WriteIndented = true // 格式化 JSON
};
string json = JsonSerializer.Serialize(students, options);
File.WriteAllText(filePath, json);
Console.WriteLine("\n✓ 数据已保存!");
}
catch (Exception ex)
{
Console.WriteLine($"\n✗ 保存失败: {ex.Message}");
}
}
/// <summary>
/// 从文件加载
/// </summary>
private void LoadFromFile()
{
if (!File.Exists(filePath))
{
return;
}
try
{
string json = File.ReadAllText(filePath);
students = JsonSerializer.Deserialize<List<Student>>(json) ?? new List<Student>();
Console.WriteLine($"✓ 已加载 {students.Count} 名学生");
}
catch (Exception ex)
{
Console.WriteLine($"✗ 加载失败: {ex.Message}");
students = new List<Student>();
}
}
}
}
代码讲解:
LINQ 查询:使用FirstOrDefault、Where、Any等方法查询数据LINQ 统计:使用Count、Average、Max、Min等方法统计数据LINQ 排序:使用OrderBy、OrderByDescending排序switch 表达式:使用新语法简化条件判断JsonSerializer:使用 System.Text.Json 序列化和反序列化Dictionary:使用字典存储分数段统计结果
第四步:实现主程序
修改 Program.cs 文件:
using System;
namespace StudentManagement
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("===== 学生信息管理系统 =====");
Console.WriteLine("欢迎使用!\n");
StudentManager manager = new StudentManager();
bool running = true;
while (running)
{
ShowMenu();
string choice = Console.ReadLine();
Console.WriteLine();
try
{
switch (choice)
{
case "1":
AddStudent(manager);
break;
case "2":
QueryStudent(manager);
break;
case "3":
UpdateStudent(manager);
break;
case "4":
DeleteStudent(manager);
break;
case "5":
DisplayStudents(manager);
break;
case "6":
manager.ShowStatistics();
break;
case "7":
manager.SaveToFile();
running = false;
break;
default:
Console.WriteLine("✗ 无效的选项,请重新选择!");
break;
}
}
catch (Exception ex)
{
Console.WriteLine($"\n✗ 发生错误: {ex.Message}");
}
if (running)
{
Console.WriteLine("\n按任意键继续...");
Console.ReadKey();
Console.Clear();
}
}
Console.WriteLine("\n感谢使用!再见!\n");
}
/// <summary>
/// 显示菜单
/// </summary>
static void ShowMenu()
{
Console.WriteLine("\n===== 学生信息管理系统 =====");
Console.WriteLine("1. 添加学生");
Console.WriteLine("2. 查询学生");
Console.WriteLine("3. 修改学生信息");
Console.WriteLine("4. 删除学生");
Console.WriteLine("5. 显示所有学生");
Console.WriteLine("6. 统计信息");
Console.WriteLine("7. 保存并退出");
Console.WriteLine("===========================");
Console.Write("请选择操作: ");
}
/// <summary>
/// 添加学生
/// </summary>
static void AddStudent(StudentManager manager)
{
Console.WriteLine("--- 添加学生 ---");
Console.Write("请输入学号: ");
string studentId = Console.ReadLine();
Console.Write("请输入姓名: ");
string name = Console.ReadLine();
Console.Write("请输入年龄: ");
if (!int.TryParse(Console.ReadLine(), out int age))
{
Console.WriteLine("✗ 年龄格式错误!");
return;
}
Console.Write("请输入成绩: ");
if (!double.TryParse(Console.ReadLine(), out double score))
{
Console.WriteLine("✗ 成绩格式错误!");
return;
}
var student = new Student(studentId, name, age, score);
manager.AddStudent(student);
}
/// <summary>
/// 查询学生
/// </summary>
static void QueryStudent(StudentManager manager)
{
Console.WriteLine("--- 查询学生 ---");
Console.WriteLine("1. 按学号查询");
Console.WriteLine("2. 按姓名查询");
Console.Write("请选择查询方式: ");
string choice = Console.ReadLine();
if (choice == "1")
{
Console.Write("请输入学号: ");
string studentId = Console.ReadLine();
var student = manager.GetStudentById(studentId);
if (student == null)
{
Console.WriteLine("✗ 找不到该学生!");
}
else
{
Console.WriteLine("\n查询结果:");
Console.WriteLine($"学号: {student.StudentId}");
Console.WriteLine($"姓名: {student.Name}");
Console.WriteLine($"年龄: {student.Age}");
Console.WriteLine($"成绩: {student.Score:F1}");
Console.WriteLine($"等级: {student.GetGrade()}");
}
}
else if (choice == "2")
{
Console.Write("请输入姓名(支持模糊查询): ");
string name = Console.ReadLine();
var students = manager.GetStudentsByName(name);
if (students.Count == 0)
{
Console.WriteLine("✗ 找不到匹配的学生!");
}
else
{
Console.WriteLine($"\n找到 {students.Count} 名学生:");
Console.WriteLine($"{'学号',-12}{'姓名',-10}{'年龄',-6}{'成绩',-8}等级");
Console.WriteLine(new string('-', 50));
foreach (var s in students)
{
Console.WriteLine(s);
}
}
}
else
{
Console.WriteLine("✗ 无效的选项!");
}
}
/// <summary>
/// 修改学生信息
/// </summary>
static void UpdateStudent(StudentManager manager)
{
Console.WriteLine("--- 修改学生信息 ---");
Console.Write("请输入要修改的学生学号: ");
string studentId = Console.ReadLine();
var existingStudent = manager.GetStudentById(studentId);
if (existingStudent == null)
{
Console.WriteLine("✗ 找不到该学生!");
return;
}
Console.WriteLine($"\n当前信息: {existingStudent.Name}, {existingStudent.Age}岁, {existingStudent.Score:F1}分");
Console.WriteLine("请输入新信息(直接回车保持原值):");
Console.Write($"新学号[{existingStudent.StudentId}]: ");
string newId = Console.ReadLine();
if (string.IsNullOrWhiteSpace(newId)) newId = existingStudent.StudentId;
Console.Write($"新姓名[{existingStudent.Name}]: ");
string newName = Console.ReadLine();
if (string.IsNullOrWhiteSpace(newName)) newName = existingStudent.Name;
Console.Write($"新年龄[{existingStudent.Age}]: ");
string ageInput = Console.ReadLine();
int newAge = string.IsNullOrWhiteSpace(ageInput) ? existingStudent.Age : int.Parse(ageInput);
Console.Write($"新成绩[{existingStudent.Score:F1}]: ");
string scoreInput = Console.ReadLine();
double newScore = string.IsNullOrWhiteSpace(scoreInput) ? existingStudent.Score : double.Parse(scoreInput);
var updatedStudent = new Student(newId, newName, newAge, newScore);
manager.UpdateStudent(studentId, updatedStudent);
}
/// <summary>
/// 删除学生
/// </summary>
static void DeleteStudent(StudentManager manager)
{
Console.WriteLine("--- 删除学生 ---");
Console.Write("请输入要删除的学生学号: ");
string studentId = Console.ReadLine();
var student = manager.GetStudentById(studentId);
if (student == null)
{
Console.WriteLine("✗ 找不到该学生!");
return;
}
Console.Write($"确认删除 {student.Name} ({student.StudentId})? (y/n): ");
string confirm = Console.ReadLine();
if (confirm.ToLower() == "y")
{
manager.DeleteStudent(studentId);
}
else
{
Console.WriteLine("已取消删除");
}
}
/// <summary>
/// 显示所有学生
/// </summary>
static void DisplayStudents(StudentManager manager)
{
Console.WriteLine("排序方式:");
Console.WriteLine("1. 按学号");
Console.WriteLine("2. 按姓名");
Console.WriteLine("3. 按年龄");
Console.WriteLine("4. 按成绩");
Console.Write("请选择(直接回车默认按学号): ");
string choice = Console.ReadLine();
string sortBy = choice switch
{
"2" => "name",
"3" => "age",
"4" => "score",
_ => "id"
};
manager.DisplayAllStudents(sortBy);
}
}
}
代码讲解:
- 使用
try-catch捕获所有可能的异常 - 每个功能都封装成独立的方法
- 提供用户友好的提示和确认
- 支持保持原值的修改方式
- 使用
switch 表达式简化代码
🎮 运行演示
1. 添加学生
===== 学生信息管理系统 =====
欢迎使用!
✓ 已加载 0 名学生
===== 学生信息管理系统 =====
1. 添加学生
2. 查询学生
3. 修改学生信息
4. 删除学生
5. 显示所有学生
6. 统计信息
7. 保存并退出
===========================
请选择操作: 1
--- 添加学生 ---
请输入学号: 2024001
请输入姓名: 张三
请输入年龄: 20
请输入成绩: 85.5
✓ 添加成功!
2. 显示所有学生
请选择操作: 5
排序方式:
1. 按学号
2. 按姓名
3. 按年龄
4. 按成绩
请选择(直接回车默认按学号): 4
===== 学生列表 =====
学号 姓名 年龄 成绩 等级
--------------------------------------------------
2024003 王五 22 92.0 优秀
2024001 张三 20 85.5 良好
2024002 李四 21 78.0 中等
--------------------------------------------------
共 3 名学生
3. 统计信息
请选择操作: 6
===== 统计信息 =====
总人数: 3
平均分: 85.17
最高分: 92.0
最低分: 78.0
及格人数: 3
及格率: 100.0%
分数段分布:
优秀(90-100): 1 人 (33.3%)
良好(80-89): 1 人 (33.3%)
中等(70-79): 1 人 (33.3%)
及格(60-69): 0 人 (0.0%)
不及格(0-59): 0 人 (0.0%)
最高分学生: 王五 (2024003) - 92.0分
最低分学生: 李四 (2024002) - 78.0分
====================
📚 知识点总结
这个项目用到了以下知识点:
| 知识点 | 说明 | 在项目中的应用 |
|---|---|---|
| 面向对象 | 类、属性、方法、封装 | Student 和 StudentManager 类 |
| 数据验证 | 输入验证、边界检查 | Validate() 方法 |
| 集合操作 | List<T> 增删改查 | 管理学生列表 |
| LINQ 查询 | Where、FirstOrDefault、Any | 查询学生 |
| LINQ 统计 | Count、Average、Max、Min | 统计功能 |
| LINQ 排序 | OrderBy、OrderByDescending | 排序显示 |
| JSON 序列化 | JsonSerializer | 数据持久化 |
| 异常处理 | try-catch | 错误处理 |
| 字符串格式化 | {value,-width:format} | 格式化输出 |
| switch 表达式 | 新语法 | 简化条件判断 |
💡 代码优化建议
1. 使用接口抽象数据存储
public interface IDataStorage
{
void Save<T>(List<T> data);
List<T> Load<T>();
}
public class JsonStorage : IDataStorage
{
// JSON 实现
}
public class XmlStorage : IDataStorage
{
// XML 实现
}
2. 添加分页功能
public List<Student> GetStudentsPage(int pageNumber, int pageSize)
{
return students
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize)
.ToList();
}
3. 使用属性验证特性
using System.ComponentModel.DataAnnotations;
public class Student
{
[Required]
[StringLength(10)]
public string StudentId { get; set; }
[Range(15, 30)]
public int Age { get; set; }
[Range(0, 100)]
public double Score { get; set; }
}
4. 实现批量导入
public void ImportFromCsv(string csvFilePath)
{
var lines = File.ReadAllLines(csvFilePath);
foreach (var line in lines.Skip(1)) // 跳过表头
{
var parts = line.Split(',');
var student = new Student(parts[0], parts[1],
int.Parse(parts[2]), double.Parse(parts[3]));
AddStudent(student);
}
}
🚀 扩展功能建议
完成基本功能后,可以尝试添加:
课程管理
- 支持多门课程
- 每门课程有独立成绩
- 计算总分和平均分
班级管理
- 学生分配到不同班级
- 按班级统计和查询
- 班级排名
成绩分析
- 成绩趋势分析
- 生成图表(使用库如 ScottPlot)
- 导出分析报告
高级查询
- 组合条件查询
- 成绩范围查询
- 年龄段统计
数据导出
- 导出为 Excel
- 导出为 PDF 报表
- 打印功能
权限管理
- 教师和管理员角色
- 不同权限级别
- 操作日志
🎯 练习任务
基础任务:完整实现上述代码,确保所有功能正常运行
进阶任务:添加分页显示功能,每页显示10条记录
挑战任务:实现 CSV 文件的导入和导出功能
超级挑战:添加多门课程支持,每个学生可以有多门课程成绩
参考实现:CSV 导出功能
// 在 StudentManager 类中添加
public void ExportToCsv(string csvFilePath)
{
try
{
using (StreamWriter writer = new StreamWriter(csvFilePath))
{
// 写入表头
writer.WriteLine("学号,姓名,年龄,成绩,等级");
// 写入每个学生
foreach (var student in students)
{
writer.WriteLine($"{student.StudentId},{student.Name}," +
$"{student.Age},{student.Score},{student.GetGrade()}");
}
}
Console.WriteLine($"\n✓ 已导出到 {csvFilePath}");
}
catch (Exception ex)
{
Console.WriteLine($"\n✗ 导出失败: {ex.Message}");
}
}
// 在主菜单中添加选项
case "8":
Console.Write("请输入导出文件名: ");
string fileName = Console.ReadLine();
manager.ExportToCsv(fileName);
break;
📝 项目小结
恭喜你完成了第三个项目!通过这个项目,你应该:
- ✅ 掌握了完整的 CRUD 操作
- ✅ 熟练使用 LINQ 进行数据查询和统计
- ✅ 学会了数据验证的重要性和实现方式
- ✅ 理解了面向对象设计的实际应用
- ✅ 掌握了 JSON 序列化和反序列化
- ✅ 学会了如何设计合理的类结构
- ✅ 实现了复杂的业务逻辑
🎯 下一步
完成学生管理系统后,下一个项目我们要做一个"图书管理系统",学习更复杂的关系管理和事务处理!
💪 自我检测
- [ ] 能够独立设计类和属性
- [ ] 会使用 LINQ 进行复杂查询
- [ ] 掌握数据验证的实现方法
- [ ] 能够实现完整的 CRUD 操作
- [ ] 理解 JSON 序列化和反序列化
- [ ] 会使用 LINQ 进行数据统计
- [ ] 能够处理各种边界情况和异常
第三个项目完成了!你已经能够开发实用的管理系统了!继续努力!💪
