Swifter.Json 是一个高性能、功能丰富的 C# JSON 序列化和反序列化工具。它使用了许多优秀的技术来提高序列化和反序列化的速度,并且具有许多有用的功能,例如支持多种日期时间格式、使用 LINQ查询序列化对象、支持循环引用等。接下来我将逐一介绍它的几个主要特点。
1、高性能
Swifter.Json 采用了诸如 Span、Array Pool、Ref Return、IL Emit 等技术,来提高性能。它采用了正反序列化分离的方式来避免额外的类型推断等开销,还支持多种类型的转换,例如字符串转为枚举类型,数字类型转为布尔类型等。
2、支持多种日期时间格式
Swifter.Json 支持多种日期时间格式,可以使用全局设置来配置它的序列化和反序列化方式,也可以在运行时动态设置。它支持的日期时间格式包括 ISO8601、Unix 时间戳、JAVAScript 时间戳 和 Microsoft JSON 日期时间格式等。
3、使用 LINQ 查询序列化对象
Swifter.Json 可以使用 LINQ 查询语法序列化对象并生成复杂的 JSON 结构。例如,可以使用 Group By 子句,将相同类型的对象序列化成列表。
4、支持循环引用
Swifter.Json 支持处理循环引用的对象,例如某个对象的属性会引用该对象本身。它使用对象标识符和索引表来避免序列化时出现死循环。Swifter.Json 还支持自定义标识符的生成方式和其他选项来更好地处理循环引用。
5、支持动态序列化
Swifter.Json 支持动态序列化,这意味着可以通过反射获取对象的信息,生成序列化代码并缓存起来以提高序列化的速度。动态序列化还支持处理匿名类型等。
6、具有可插拔的架构
Swifter.Json 是通过不同的接口和类密切合作来实现其功能的,这些接口和类具有可插拔架构,可以根据需要进行替换或扩展。
以上是 Swifter.Json 的主要特点,Swifter.Json 在性能、功能和灵活性方面都表现出了很高的水平,可以称之为 C# 领域中的 JSON 序列化和反序列化利器。
下面我将列出几个具体的示例:
1、实现对象的序列化和反序列化。
using Swifter.Json;
// 定义一个简单的实体类
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
// 将对象序列化为 JSON 字符串
var person = new Person { Name = "Tom", Age = 18 };
string json = JsonFormatter.SerializeObject(person);
// 反序列化 JSON 字符串为对象
var person2 = JsonFormatter.DeserializeObject<Person>(json);
2、实现基于 LINQ 的对象序列化
using System.Linq.Expressions;
using Swifter.Json;
// 定义一个较为复杂的实体类
public enum Gender { Male, Female }
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Gender Gender { get; set; }
}
// 使用 LINQ 根据性别分组,将相同性别的人员序列化为列表
var persons = new List<Person> {
new Person { Name = "Tom", Age = 18, Gender = Gender.Male },
new Person { Name = "Jerry", Age = 19, Gender = Gender.Male },
new Person { Name = "Lucy", Age = 21, Gender = Gender.Female }
};
var json = JsonFormatter.SerializeObject(
persons.GroupBy(p => p.Gender)
.Select(g => new { Gender = g.Key, Persons = g.ToList() })
.ToList());
3、处理循环引用的对象序列化
using Swifter.Json;
// 定义一个带有循环引用的类
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
public Person Friend { get; set; }
}
var person1 = new Person { Name = "Tom", Age = 18 };
var person2 = new Person { Name = "Jerry", Age = 19, Friend = person1 };
person1.Friend = person2;
// 将对象序列化为 JSON 字符串
var json = JsonFormatter.SerializeObject(person1,
new SerializeOptions { IgnoreNullValues = true,
SerializeReferenceLoopHandling = ReferenceLoopHandling.Serialize });
在上面的例子中,person1 对象中的 Friend 属性引用了 person2,而 person2 又引用了 person1 对象本身,这就是循环引用。在序列化时,我们设置了
ReferenceLoopHandling.Serialize,这就可以避免序列化时出现死循环。
4、支持多种日期时间格式
using Swifter.Json;
// 定义一个带有日期时间属性的实体类
public class Person
{
public string Name { get; set; }
public DateTime BirthDay { get; set; }
}
var person = new Person { Name = "Tom", BirthDay = DateTime.Now };
// 将对象序列化为 JSON 字符串,使用 Unix 时间戳格式
var json1 = JsonFormatter.SerializeObject(person,
new SerializeOptions { DateTimeFormat = DateTimeFormats.UnixMilliseconds });
// 将对象序列化为 JSON 字符串,使用 ISO8601 格式
var json2 = JsonFormatter.SerializeObject(person,
new SerializeOptions { DateTimeFormat = DateTimeFormats.ISO8601 });
// 将对象序列化为 JSON 字符串,使用 Microsoft JSON 日期时间格式
var json3 = JsonFormatter.SerializeObject(person,
new SerializeOptions { DateTimeFormat = DateTimeFormats.Microsoft });
在上面的例子中,我们演示了如何通过设置 DateTimeFormat 参数来指定不同的日期时间格式,包括 Unix 时间戳、ISO8601 格式和 Microsoft JSON 日期时间格式。
5、支持自定义实体的序列化和反序列化方式
using System;
using Swifter.Json;
// 定义一个实体类
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
// 定义一个自定义的 Person 序列化器
public class PersonJsonFormatter : IJsonFormatter<Person>
{
public Person Deserialize(JsonReader reader, JsonFormatterResolver formatterResolver)
{
if (reader is null) throw new ArgumentNullException(nameof(reader));
// 读取对象开始标记
if (reader.Read() == false || reader.TokenType != JsonTokenType.BeginObject)
throw new JsonFormatException();
var person = new Person();
while (reader.Read() && reader.TokenType != JsonTokenType.EndObject)
{
// 读取属性
switch (reader.ReadPropertyName())
{
case nameof(Person.Name):
person.Name = reader.ReadString();
break;
case nameof(Person.Age):
person.Age = reader.ReadInt32();
break;
}
}
return person;
}
public void Serialize(JsonWriter writer, Person value, JsonFormatterResolver formatterResolver)
{
if (writer is null) throw new ArgumentNullException(nameof(writer));
if (value is null) throw new ArgumentNullException(nameof(value));
// 写入对象开始标记
writer.WriteBeginObject();
// 写入属性
writer.WritePropertyName(nameof(Person.Name));
writer.WriteString(value.Name);
writer.WritePropertyName(nameof(Person.Age));
writer.WriteInt32(value.Age);
// 写入对象结束标记
writer.WriteEndObject();
}
}
// 将自定义的 Person 序列化器添加到默认格式解析器中
JsonFormatterResolverExtensions.Register(new PersonJsonFormatter(), overrideExisting: true);
// 将对象序列化为 JSON 字符串
var person = new Person { Name = "Tom", Age = 18 };
var json = JsonFormatter.SerializeObject(person);
在上面的例子中,我们演示了如何实现自定义的实体类序列化和反序列化方式,并将其添加到格式解析器中。这样我们可以通过调用 JsonSerializer 中的方法对自定义的实体类进行序列化和反序列化。
6、使用动态类型实现对象序列化
using Swifter.Json;
// 定义一个动态类型的对象
var dynamicObj = new { Name = "Tom", Age = 18 };
// 将动态类型对象序列化为 JSON 字符串
var json = JsonFormatter.SerializeObject(dynamicObj);
// 反序列化 JSON 字符串为动态类型对象
var dynamicObj2 = JsonFormatter.DeserializeObject(json);
在上面的例子中,我们演示了如何使用动态类型进行对象序列化和反序列化。需要注意的是,使用动态类型序列化和反序列化可能会带来额外的性能开销。
除了以上示例,Swifter.Json 还提供许多其他功能,例如支持使用 JSONPath 方式进行对象选择、支持对象动态转换等。后续如有时间再继续和大家分享Swifter.Json的学习笔记!