您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > C/C++/C#

C# Swifter.Json 浅析

时间:2023-06-12 13:40:40  来源:今日头条  作者:步伐科技

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



Tags:C#   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
C# 中15个值得收藏的开源项目推荐
在开源的世界里,C# 编程语言也占有一席之地。这些开源项目涵盖了多个领域,从框架、库到工具,它们为C#开发者提供了丰富的资源和工具,帮助他们更高效地开发、测试和部署应用程序...【详细内容】
2024-03-20  Search: C#  点击:(30)  评论:(0)  加入收藏
C#异步编程:Task.Run vs. async-await,掌握基础与高级用法
概述:C#中的异步编程有两主要方式:Task.Run用于在后台线程执行同步操作,而async-await更适用于清晰表达异步流程。基础用法展示了它们的简单应用,高级用法则演示了它们的结合使...【详细内容】
2024-03-09  Search: C#  点击:(23)  评论:(0)  加入收藏
C# 线程本地存储为什么线程间值不一样
为什么用 ThreadStatic 标记的字段,只有第一个线程拿到了初始值,其他线程都是默认值,让我能不能帮他解答一下,尼玛,我也不是神仙什么都懂,既然问了,那我试着帮他解答一下,也给后面类...【详细内容】
2024-01-26  Search: C#  点击:(68)  评论:(0)  加入收藏
C# 登顶!超越Java或非空想
整理丨诺亚出品 | 51CTO技术栈(微信号:blog51cto)近日,TIOBE编程社区公布年度编程语言,此次摘得这一桂冠的是C#。这也是C#在TIOBE二十多年评选历史中首次赢得这一年度大奖。C#虽...【详细内容】
2024-01-15  Search: C#  点击:(116)  评论:(0)  加入收藏
C#进程间消息传递
C#是一种流行的编程语言,它可以用于开发Windows应用程序。在开发Windows应用程序时,有时需要进行进程间通信,以实现不同进程之间的数据传递和交互。C#提供了多种方式来进行进程...【详细内容】
2024-01-01  Search: C#  点击:(104)  评论:(0)  加入收藏
搞懂C#文件压缩:SharpZipLib vs. DotNetZip,实用代码一网打尽!
在C#中,有两个热门的文件压缩解析类库分别是SharpZipLib和DotNetZip。以下是它们的简要介绍以及使用实例代码。1. SharpZipLib功能: 支持ZIP和GZip格式的压缩和解压缩。 提供...【详细内容】
2023-12-31  Search: C#  点击:(12)  评论:(0)  加入收藏
探秘C#中的秘密通道:五种引人注目的方法调用内部或私有方法
在 C# 中,可以使用不同的方法调用内部或私有方法。下面分别介绍通过反射、MethodInfo.CreateDelegate、表达式(树)、动态方法(call)、动态方法(calli)这五种方法。1. 通过反射方法...【详细内容】
2023-11-24  Search: C#  点击:(21)  评论:(0)  加入收藏
C#参数传递
前几天一个学员在学习C#与参数传递交互时,也不知道参数传递可以用来做什么 。下面我们就详细讲讲C# 和参数传递交互的相关知识。C#是一种面向对象的编程语言,支持多种参数传...【详细内容】
2023-11-11  Search: C#  点击:(215)  评论:(0)  加入收藏
C#与高级控件
前几天一个学员在学习C#与高级控件交互时,也不知道高级控件可以用来做什么 。下面我们就详细讲讲C# 和高级控件交互的相关知识。C#是一种功能丰富的面向对象编程语言,它包含...【详细内容】
2023-11-10  Search: C#  点击:(257)  评论:(0)  加入收藏
如何在C#客户端程序中无缝集成Python算法
背景介绍在软件开发领域,C#是一种广泛应用的面向对象编程语言,具有强大的类型系统和丰富的库支持。它常被用于开发Windows桌面应用程序、Web应用程序和服务端应用程序等。然而...【详细内容】
2023-11-03  Search: C#  点击:(299)  评论:(0)  加入收藏
▌简易百科推荐
C++常见避坑指南
C++ 从入门到放弃?本文主要总结了在C++开发或review过程中常见易出错点做了归纳总结,希望借此能增进大家对C++的了解,减少编程出错,提升工作效率,也可以作为C++开发的避坑攻略。...【详细内容】
2024-04-03  腾讯技术工程    Tags:C++   点击:(5)  评论:(0)  加入收藏
C++ 之父反驳白宫警告:自诞生第一天起,C++ 的目标就一直是提高安全性
整理 | 郑丽媛上个月,美国白宫国家网络主任办公室(ONCD)在一份主题为《回到基础构件:通往安全软件之路》的 19 页 PDF 报告中,呼吁开发人员停止使用容易出现内存安全漏洞的编程语...【详细内容】
2024-03-25    CSDN  Tags:C++   点击:(4)  评论:(0)  加入收藏
八个 C++ 开源项目,帮助初学者进阶成长
通过参与或阅读开源项目的源代码,你可以获得丰富的实践机会。实际的项目代码比简单的教程更具挑战性,可以帮助你深入理解 C++ 的各种概念和技术。1.ThreadPool一个简单的 C++1...【详细内容】
2024-03-22  AI让生活更美好  微信公众号  Tags:C++   点击:(21)  评论:(0)  加入收藏
C# 中15个值得收藏的开源项目推荐
在开源的世界里,C# 编程语言也占有一席之地。这些开源项目涵盖了多个领域,从框架、库到工具,它们为C#开发者提供了丰富的资源和工具,帮助他们更高效地开发、测试和部署应用程序...【详细内容】
2024-03-20  程序员编程日记  微信公众号  Tags:C#   点击:(30)  评论:(0)  加入收藏
C#异步编程:Task.Run vs. async-await,掌握基础与高级用法
概述:C#中的异步编程有两主要方式:Task.Run用于在后台线程执行同步操作,而async-await更适用于清晰表达异步流程。基础用法展示了它们的简单应用,高级用法则演示了它们的结合使...【详细内容】
2024-03-09  架构师老卢  今日头条  Tags:C#   点击:(23)  评论:(0)  加入收藏
C++多线程编程:解锁性能与并发的奥秘
今天我们将深入探讨C++中的多线程编程,揭示多线程如何解锁性能潜力,提高程序的并发性能。什么是多线程?在计算机科学中,多线程是指一个进程(程序的执行实例)中的多个线程同时执行...【详细内容】
2024-02-03     AI让生活更美好  Tags:C++   点击:(69)  评论:(0)  加入收藏
C++代码优化攻略
今天我们将深入探讨C++性能优化的世界。在当今软件开发的浪潮中,高性能的代码是必不可少的。无论是开发桌面应用、移动应用,还是嵌入式系统,性能都是关键。1. 选择合适的数据结...【详细内容】
2024-01-26  AI让生活更美好  微信公众号  Tags:C++   点击:(115)  评论:(0)  加入收藏
C# 线程本地存储为什么线程间值不一样
为什么用 ThreadStatic 标记的字段,只有第一个线程拿到了初始值,其他线程都是默认值,让我能不能帮他解答一下,尼玛,我也不是神仙什么都懂,既然问了,那我试着帮他解答一下,也给后面类...【详细内容】
2024-01-26  一线码农聊技术  微信公众号  Tags:C#   点击:(68)  评论:(0)  加入收藏
C++质数检测器的设计与实现​
质数,作为数学中的一个基本概念,一直以其独特的性质吸引着众多研究者和爱好者。质数是指大于1的自然数中,除了1和它本身以外不再有其他因数的数。在实际应用中,质数检测也扮演着...【详细内容】
2024-01-15  鲨鱼编程  微信公众号  Tags:C++   点击:(115)  评论:(0)  加入收藏
C# 登顶!超越Java或非空想
整理丨诺亚出品 | 51CTO技术栈(微信号:blog51cto)近日,TIOBE编程社区公布年度编程语言,此次摘得这一桂冠的是C#。这也是C#在TIOBE二十多年评选历史中首次赢得这一年度大奖。C#虽...【详细内容】
2024-01-15    51CTO  Tags:C#   点击:(116)  评论:(0)  加入收藏
站内最新
站内热门
站内头条