前言
在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是数据持久化的关键"