C# 学习笔记 13:对象的脱水封印术 —— 序列化(JSON Serialization)
开篇:皮皮的“打包”噩梦
皮皮(Pipi)终于要给游戏做真正的存档系统了。 问题是——他的背包不是一个数字,而是一个:
List<Item>
他决定用上节课的文件操作,硬来一把。
// 🚫 皮皮的笨办法:手动拼字符串
string saveString = "";
foreach (var item in bag)
{
saveString += item.Name + "," + item.Damage + "," + item.Type + "|";
}
// 结果: "屠龙刀,999,武器|草药,10,消耗品|"
一开始还能跑,但很快灾难出现了:
- 物品名里自带逗号怎么办?
"倚天剑,仿" —— 存档直接裂开 - 以后给
Item 加个 Durability? —— 所有存读代码全部重写 - 读档要怎么拆?
Split(',') + Split('|')? —— 人没疯,代码先疯
瓜瓜(Guagua):“停停停。你这是石器时代的数据管理。 用魔法压缩机吧——JSON 序列化。”
第一关:JSON 是什么?
JSON(JavaScript Object Notation)是一种全世界通用的数据表示格式。
它的特点只有四个字:
像代码,又不是代码
{
"Name": "皮皮",
"Level": 99,
"Skills": ["火球术", "治疗术"]
}
看起来是不是很像 C#?
new Player
{
Name = "皮皮",
Level = 99,
Skills = new List<string> { "火球术", "治疗术" }
}
这正是 JSON 的强大之处:
JSON 是对象世界的“通用语言”
第二关:序列化(Serialization)——脱水封印
什么是“序列化”?
把内存中活着的对象
变成可以保存 / 传输的文本
就像:
官方神器:System.Text.Json
.NET 已经帮你准备好了一切。
using System.Text.Json; // JSON 魔法核心
实战:对象 → JSON
// 1️⃣ 准备一个对象
Monster boss = new Monster
{
Name = "魔王",
Hp = 9999
};
// 2️⃣ 施展脱水封印术
string jsonString = JsonSerializer.Serialize(boss);
// 3️⃣ 看看结果
Console.WriteLine(jsonString);
// {"Name":"魔王","Hp":9999}
// 4️⃣ 存进文件
File.WriteAllText("boss_data.json", jsonString);
震撼点在这里:
👉 对象结构 = JSON 结构
第三关:反序列化(Deserialization)——泡发复活
第二天,皮皮启动游戏,要把魔王读回来。
这一步叫:
反序列化—— 把“脱水包”重新泡成对象
核心规则:你必须告诉它“原型图纸”
// 1️⃣ 读取 JSON 字符串
string jsonString = File.ReadAllText("boss_data.json");
// 2️⃣ 按 Monster 的图纸复活
Monster loadedBoss =
JsonSerializer.Deserialize<Monster>(jsonString);
// 3️⃣ 验证
Console.WriteLine(
$"复活成功!我是 {loadedBoss.Name},HP={loadedBoss.Hp}"
);
📌 重点中的重点:
Deserialize<Monster>(...)
模具错了,要么报错,要么属性全是默认值。
第四关:真正的杀手锏 —— 列表序列化
这才是皮皮最想要的能力。
整个 List,直接存!
List<Monster> team = new List<Monster>
{
new Monster { Name = "皮皮", Hp = 100 },
new Monster { Name = "瓜瓜", Hp = 200 }
};
// 存档
string json = JsonSerializer.Serialize(team);
File.WriteAllText("team_save.json", json);
// 读档
List<Monster> loadedTeam =
JsonSerializer.Deserialize<List<Monster>>(json);
Console.WriteLine($"队伍人数:{loadedTeam.Count}");
JSON 文件内容会是:
[
{ "Name": "皮皮", "Hp": 100 },
{ "Name": "瓜瓜", "Hp": 200 }
]
📌 这一刻我们已经拥有了:
总结:序列化真正解决了什么?
今日战利品
- System.Text.Json:官方、快速、安全
真正的认知升级是:
你不再“操作字符串” 你在保存对象的结构
课后思考(非常关键)
JSON 只保存数据:
{ "Hp": 100 }
如果 Monster 类里有:
voidAttack() { ... }
❓这个方法会被存进 JSON 吗?
👉 不会。
原因是:
规则已经写在代码里, 不需要存进存档。
⏭️ 下期预告:真正的“面向对象安全”
皮皮突然发现一个严重问题:
monster.Hp = -100;
居然不报错?
任何人都能随便改血量?这太不安全了!
下一期,我们将学习——
👉 封装的艺术:属性(Properties)
给变量装上安检门, 只允许“合法修改”。
面向对象的防线,从这里开始。