CodeGym /课程 /C# SELF /JSON 语法与结构基础 JSON

JSON 语法与结构基础 JSON

C# SELF
第 47 级, 课程 0
可用

1. 回顾 JSON

JSON 的全称是 JavaScript Object Notation。虽然名字里有让人紧张的 JavaScript,但这个格式本质上与语言无关,对几乎所有(嗯,差不多所有)编程语言都很友好,包括 C#。它的设计目的就是用普通文本方便、清楚地描述数据 —— 对象、数组、列表和字典。

在现代世界里,几乎每个程序都需要和别的程序交流,JSON 已经基本成为序列化和交换结构化数据的事实标准。它随处可见:从 REST API 到保存用户设置,甚至服务间内部通信。理由很简单 —— 人能读得懂(前提是不怕大括号),解析也容易,且被所有现代语言和库支持。

为什么不用 XML?

JSON 比 XML 更简单、更短,也更容易阅读。而且没有多余的噪音和标签,更贴合大多数编程语言的数据结构。也不用折腾闭合标签、引号和其他 XML 的繁琐。总之 —— JSON 就是 更快、更简单、更方便。

2. JSON 语法的基本要素

可以把 JSON 想成一棵简单的树(或者套娃),由对象、数组和基本数据组成。我们手头有这些「积木」:

对象 (Objects)

JSON 对象 是一组 «键: 值» 对,包在花括号里 { }。

示例:

{
  "name": "Alice",
  "age": 23
}

在 C# 中,这样的结构可以表示为类或字典。

数组 (Arrays)

JSON 数组 是一个有序的元素列表(元素可以是任意类型),用方括号包起来 [ ]。

示例:

[1, 2, 3, 42]

或者:

[
  {"name": "Ivan"},
  {"name": "Olga"}
]

在 C# 中对应 List<T>、T[] 等集合。

键-值对

键总是 字符串(必须用双引号!),值可以是 JSON 允许的任意数据类型。

示例:

{
  "id": 123,
  "login": "student",
  "isActive": true
}

JSON 中的数据类型

JSON 类型 示例 说明
数字 (Number)
10, -5, 3.14
整数或小数
字符串 (String)
"hello"
总是用双引号
布尔 (Boolean)
true, false
布尔值
null
null
表示没有值
对象 (Object)
{"a":1}
字典或带字段的实体
数组 (Array)
[1,2,3]
值的序列

示例 — 综合演示:

{
  "id": 1,
  "name": "Bob",
  "scores": [10, 20, 30],
  "profile": {
    "email": "bob@mail.com",
    "phone": null
  },
  "isAdmin": false
}

看,多紧凑也多清晰地描述了一个用户对象。

3. JSON 的书写规则

字符串必须用双引号

即便很想用单引号,JSON 也不允许。正确写法:

{ "name": "Vera" }

下面这样是 错误 的:

{ 'name': 'Vera' }

键 —— 只能是字符串

和 C# 不同(在 C# 中字典的键可以是 int 或 enum),在 JSON 里键永远是字符串:

{ "2025": "C# 年", "favorite": true }

不要尾随逗号

和 C# 的数组或对象不同,JSON 在闭括号前出现多余的逗号会导致语法错误!

// 错误!(最后一个逗号不允许)
{
  "id": 10,
  "name": "Oleg",
}

正确:

{
  "id": 10,
  "name": "Oleg"
}

空格和换行

可以为了美观加上空格和换行,解析器会忽略它们。通常对“面向人”的格式使用 pretty-printed(可读的格式化)JSON,网络传输时使用 minified(压缩成一行、无空格)。

4. C# 对象如何被转换为 JSON

如果你用 System.Text.Json.JsonSerializer.Serialize() 来序列化对象,那么对象的字段和属性会变成「键-值」对。

C# 类和序列化示例

public class Book
{
    public string Title { get; set; }
    public int Pages { get; set; }
}
var book = new Book { Title = "CLR via C#", Pages = 900 };
string json = JsonSerializer.Serialize(book);
Console.WriteLine(json); // {"Title":"CLR via C#","Pages":900}

集合

  • List<int> 会变成 [1,2,3]
  • string[] 会变成 ["hi", "wow"]
  • List<Person> — 变成对象数组

字典

像 Dictionary<string, int> 这样的字典会变成一个对象:

var dict = new Dictionary<string, int>
{
    ["apples"] = 5, ["bananas"] = 10
};
string json = JsonSerializer.Serialize(dict);
// {"apples":5,"bananas":10}

5. 可视化示意:JSON 如何构建

嵌套 —— 像套娃


对象
│
├── 键值对: "name": "Alex"
├── 键值对: "hobbies": 数组
│               │
│               ├── "skiing"
│               └── "programming"
└── 键值对: "profile": 对象
                 │
                 ├── "age": 42
                 └── "city": "巴塞尔"

结果:

{
  "name": "Alex",
  "hobbies": ["skiing", "programming"],
  "profile": {
    "age": 42,
    "city": "巴塞尔"
  }
}

6. 常见错误与语法注意事项

编程世界没有完美——JSON 也有坑!如果你发送的 JSON 引号不对、多了逗号或键没用引号包起来,解析器会报错。

还有一个坑 —— 带前导零的数字。在 JSON 中这是不允许的(例如 0123 是错误)。

值得知道: 有些解析器(比如 JavaScript 的 JSON.parse)比较宽松,能“容忍”一些小错误。但大多数严格的解析器(比如 C# / .NET 的实现)会对任何语法违规报错。

7. C# 数据转 JSON 的例子

我们来实际序列化一个稍复杂的结构。假设我们的教学应用进步了:现在有学生列表,想把它们保存成 JSON 文件。

定义类:

public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
}

填充列表:

var students = new List<Student>
{
    new Student { Name = "安娜", Age = 20 },
    new Student { Name = "尼基塔", Age = 22 }
};

序列化:

using System.Text.Json;

// 将学生列表序列化成 JSON 字符串
string json = JsonSerializer.Serialize(students, new JsonSerializerOptions { WriteIndented = true });
Console.WriteLine(json);

/*
[
  {
    "Name": "安娜",
    "Age": 20
  },
  {
    "Name": "尼基塔",
    "Age": 22
  }
]
*/

看,多方便?每个学生都是 JSON 数组里的一个独立对象。

8. 小型生成器:如何手工写 JSON

有时候需要手工写 JSON,比如手动创建测试数据。下面是检查清单:

  1. 外层用花括号表示对象,外层方括号表示数组。
  2. 键必须是双引号包裹的字符串。
  3. 值可以是字符串(双引号)、数字、true、false、null、对象({})或数组([])。
  4. 元素之间用逗号分隔,但最后一个元素后不要逗号!
  5. 可以用缩进和空格提高可读性(但不是必须的)。
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION