<返回更多

C# Swifter.Json 浅析

2023-06-12  今日头条  步伐科技
加入收藏

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的学习笔记!

声明:本站部分内容来自互联网,如有版权侵犯或其他问题请与我们联系,我们将立即删除或处理。
▍相关推荐
更多资讯 >>>