【C#学习Day15笔记】拆箱装箱、 Equals与== 、文件读取IO
前言
在C#第15天的学习中,我深入探索了类型转换机制、对象比较原理和文件操作技术三大核心主题。这些知识是构建高效、健壮程序的关键基础。本文完整保留我的课堂实践代码和命名体系,通过结构化梳理帮助大家掌握这些核心概念。所有代码示例均来自我的实际操作,包含从基础到进阶的完整学习过程!
一、拆箱装箱:值类型与引用类型的转换
1. 基础概念与实现
// 装箱:值类型 → 引用类型
int a = 1;
object b = a; // 装箱操作// 拆箱:引用类型 → 值类型
object c = 1;
int d = (int)c; // 拆箱操作
2. 内存机制解析
3. 性能影响与最佳实践
操作 | 性能开销 | 使用建议 |
---|---|---|
装箱 | 高(内存分配+数据复制) | 避免在循环中使用 |
拆箱 | 中(类型检查+数据复制) | 确保类型兼容 |
泛型集合 | 无(避免装箱拆箱) | 优先使用List |
二、Equals与==:对象比较的深层解析
1. 值类型比较
int x = 10;
int y = 10;// == 运算符比较
Console.WriteLine(x == y); // true// Equals方法比较
Console.WriteLine(x.Equals(y)); // true
2. 引用类型比较
class Person
{public int Age { get; set; }public string Name { get; set; }public Person(int age, string name){Age = age;Name = name;}
}Person p1 = new Person(18, "张三");
Person p2 = new Person(18, "张三");// == 默认比较引用地址
Console.WriteLine(p1 == p2); // false// Equals默认比较引用地址
Console.WriteLine(p1.Equals(p2)); // false
3. 重写Equals实现值比较
class Person
{// ...其他代码同上...// 重写Equals方法public override bool Equals(object obj){// 类型检查if (obj == null || GetType() != obj.GetType())return false;Person p = (Person)obj;return Age == p.Age && Name == p.Name;}// 重写GetHashCode(推荐与Equals一起重写)public override int GetHashCode(){return Age.GetHashCode() ^ Name.GetHashCode();}
}// 使用重写后的Equals
Console.WriteLine(p1.Equals(p2)); // true
4. 比较操作决策表
比较场景 | 推荐方式 | 注意事项 |
---|---|---|
值类型相等 | == 或 Equals | 两者行为相同 |
引用类型地址相等 | == | 默认行为 |
引用类型值相等 | 重写 Equals | 需同时重写 GetHashCode |
字符串内容相等 | == 或 Equals | 字符串已特殊处理 |
三、文件IO操作:数据持久化技术
1. FileStream基础操作
// 创建文件信息对象
FileInfo fi = new FileInfo("data.txt");// 写入文件
using (FileStream writeStream = fi.OpenWrite())
{byte[] data = { 65, 66, 67, 68, 69 };writeStream.Write(data, 0, data.Length);
}// 读取文件
using (FileStream readStream = fi.OpenRead())
{byte[] buffer = new byte[fi.Length];int bytesRead = readStream.Read(buffer, 0, buffer.Length);foreach (byte b in buffer){Console.WriteLine(b);}
}
2. StreamReader/Writer高级操作
// 获取动态路径
string path = Path.Combine(Directory.GetCurrentDirectory(), "data.txt");// 写入数据
using (StreamWriter sw = new StreamWriter(path, true)) // true表示追加模式
{sw.WriteLine("张三今天打游戏了");sw.WriteLine("李四今天游泳了");sw.WriteLine("王五今天吃饭了");
}// 读取数据
using (StreamReader sr = new StreamReader(path))
{string content = sr.ReadToEnd();string[] lines = content.Split('\n');foreach (string line in lines){if (line.Contains("张三")){Console.WriteLine("找到张三的记录");}}
}
3. 文件操作最佳实践
路径处理:
- 使用
Path.Combine()
构建路径 - 使用
Directory.GetCurrentDirectory()
获取当前目录 - 避免硬编码绝对路径
- 使用
资源管理:
- 始终使用
using
语句确保资源释放 - 处理文件不存在异常
- 检查磁盘空间
- 始终使用
性能优化:
- 使用缓冲区减少IO操作
- 异步读写大文件
- 批量处理小文件
四、综合案例:学生成绩管理系统
1. 学生类实现
class Student
{public string Name { get; set; }public int Score { get; set; }public Student(string name, int score){Name = name;Score = score;}// 重写Equals实现值比较public override bool Equals(object obj){if (obj is Student other)return Name == other.Name && Score == other.Score;return false;}public override int GetHashCode(){return Name.GetHashCode() ^ Score;}
}
2. 文件存储与加载
class ScoreManager
{private List<Student> students = new List<Student>();private string filePath;public ScoreManager(string path){filePath = path;LoadData();}// 加载数据private void LoadData(){if (File.Exists(filePath)){using (StreamReader sr = new StreamReader(filePath)){string line;while ((line = sr.ReadLine()) != null){string[] parts = line.Split(',');if (parts.Length == 2 && int.TryParse(parts[1], out int score)){students.Add(new Student(parts[0], score));}}}}}// 保存数据public void SaveData(){using (StreamWriter sw = new StreamWriter(filePath)){foreach (Student s in students){sw.WriteLine($"{s.Name},{s.Score}");}}}// 添加学生public void AddStudent(Student student){students.Add(student);}// 查找学生public Student FindStudent(string name){return students.Find(s => s.Name == name);}
}
3. 系统使用示例
// 初始化管理器
ScoreManager manager = new ScoreManager("scores.txt");// 添加学生
manager.AddStudent(new Student("张三", 90));
manager.AddStudent(new Student("李四", 85));// 保存数据
manager.SaveData();// 查找学生
Student found = manager.FindStudent("张三");
if (found != null)
{Console.WriteLine($"找到学生: {found.Name}, 成绩: {found.Score}");
}// 比较学生
Student s1 = new Student("王五", 80);
Student s2 = new Student("王五", 80);
Console.WriteLine(s1.Equals(s2)); // true
学习总结与进阶建议
核心知识图谱
关键编程原则
类型转换:
- 避免不必要的装箱拆箱
- 使用泛型集合替代非泛型集合
- 优先使用
as
和is
进行安全转换
对象比较:
- 值类型直接使用
==
- 引用类型按需重写
Equals
- 重写
Equals
时同步重写GetHashCode
- 值类型直接使用
文件操作:
- 使用
using
确保资源释放 - 处理所有可能的IO异常
- 使用相对路径增强可移植性
- 使用
实战项目建议
类型系统应用:
- 实现高性能数值计算库
- 开发类型安全的数据容器
- 创建泛型缓存系统
对象比较实践:
- 实现深度比较工具
- 开发自定义集合类
- 创建对象差异检测器
文件IO实战:
- 开发配置管理系统
- 实现数据导入导出功能
- 创建日志记录模块
编程箴言
"理解类型转换是性能优化的基础,掌握对象比较是正确性的保障,善用文件IO是数据持久化的关键"