65.9K
CodeProject 正在变化。 阅读更多。
Home

fastJSON - 最小、最快的 Polymorphic JSON 序列化器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.91/5 (400投票s)

2011年2月19日

CPOL

37分钟阅读

viewsIcon

6433668

downloadIcon

66388

在本文中,我将演示 fastJSON 为什么是最小、最快的 Polymorphic JSON 序列化器(支持 Silverlight 4、MonoDroid 和 .NET Core)。

前言

代码现已托管在

我将尽最大努力保持本文档和存储库的同步。

安全警告

我从 HP Enterprise Security Group 那里得知,使用 $type 扩展可能会不安全,所以请明智地使用它,并只用于已知的 JSON 源,不要用于公共面向的源,以确保安全。

引言

这是最小、最快的 Polymorphic JSON 序列化器,之所以说它最小,是因为编译后只有 25KB;之所以说它最快,是因为在大多数情况下它确实是最快的(参见性能测试部分);之所以说它是 Polymorphic,是因为它可以在运行时正确地序列化和反序列化以下情况,无论您传入什么对象。

class animal { public string Name { get; set;} }
class cat: animal { public int legs { get; set;} }
class dog : animal { public bool tail { get; set;} }
class zoo { public List<animal> animals { get; set;} }

var zoo1 = new zoo();

zoo1.animals = new List<animal>();
zoo1.animals.Add(new cat());
zoo1.animals.Add(new dog());

这一点非常重要,因为它极大地简化了您的编码,并且是面向对象编程的基石。奇怪的是,很少有序列化器能处理这种情况,甚至 .NET 中的 XmlSerializer 也做不到,您必须费尽周折才能使其工作。此外,如果您想替换大多数应用程序中使用的 BinaryFormatter 序列化器(它支持任何 .NET 对象结构),这一点是必须的(参见我的 WCF Killer 文章)。

JSON 是什么以及为什么使用 JSON

JSON(JavaScript Object Notation)是一种由 Douglas Crockford 大约在 1999 年发明的人类可读的文本格式,主要用作 Web 应用程序的数据交换格式(参见 www.JSON.org)。与(之前使用的)XML 相比,它的优点包括:

  • 类似 XML 的结构化数据格式
  • 高信噪比,换句话说,它消除了不属于数据本身的额外字符(XML 中的尖括号和斜杠)。
  • 紧凑的数据格式
  • 简单的解析规则,使得数据处理简便快捷。

因此,它适用于以下场景:

  • 平台之间(例如 Java 和 .NET 服务)通过网络进行数据交换。
  • 数据存储:MongoDB(www.mongodb.org)使用 JSON 作为内部存储格式。

此实现的特点

  • 仅 3 个类 + 2 个辅助类:1158 行代码
  • 符合 JSON 标准,并增加了以下扩展:
    • "$type" 用于表示对象类型信息([ Json.NET 也这样做])。
    • "$schema" 用于表示数据集的模式信息。
    • "$map" 用于在运行时将对象分配给 object 类型时进行后期类型处理。
    • "$types" 用于全局类型定义,实例通过数字引用此类型字典(可减小 JSON 大小,适用于大量嵌入类型)。
  • 支持 .NET 2.0+:下方替代方案列表中的一些实现至少需要 .NET 3.5。
  • 极小的体积:编译后仅 25KB。
  • 惊人的速度(参见性能测试部分)。
  • 可动态创建类型。
  • 支持 GuidDatasetDictionaryHashtable 和泛型列表。
  • 支持可空类型。
  • 字节数组作为 Base64 字符串处理。
  • 支持多态对象集合。
  • 线程安全。
  • 支持值类型数组(例如 int[]char[] 等)。
  • 支持值类型泛型列表(例如 List<int> 等)。
  • 支持特殊情况 List<object[]>(适用于批量数据传输)。
  • 支持嵌套类(例如 Sales.Customer)。
  • 支持将多态 object 类型反序列化为原始类型(例如 object ReturnEntity = Guid, DataSet, valuetype, new object[] { object1, object2 } )[适用于网络通信]。
  • 能够禁用序列化时的扩展,以满足 JSON 纯粹主义者(例如,输出中不包含 $type$map)。
  • 能够将标准 JSON 反序列化到您指定的类型,但不保证多态性。
  • Dictionary<string,string> 提供特殊优化的输出。
  • 覆盖 null 值输出。
  • 支持属性上的 XmlIgnore 特性。
  • 支持 DataTable
  • 通过 IndentOutput 属性支持缩进的 JSON 输出。
  • 支持 SilverLight 4.0+。
  • RegisterCustomType() 用于用户定义的、非 fastJSON 内置的类型(如 TimeSpanPoint 等)。
    • 此功能必须通过 CUSTOMTYPE 编译器指令启用,因为它会带来约 1% 的性能损失。
    • 您将序列化器和反序列化器例程作为委托提供。
  • 增加了对公共字段的支持。
  • 增加了 ShowReadOnlyProperties 来控制只读属性的输出(默认值为 false,表示不输出)。
  • 自动 UTC datetime 转换(如果日期以 "Z" 结尾,符合 JSON 标准)。
  • 增加了 UseUTCDateTime 属性来控制 UTC datetime 的输出。
  • Dictionary<string, > 现在得到最优存储,而不是 K V 格式。
  • 支持序列化器中的匿名类型(目前反序列化不可用)。
  • 支持动态类型
  • 支持对象结构中的循环引用
  • 支持多维数组,例如 int[][]

局限性

  • 目前无法反序列化值类型数组属性(例如 int[]char[] 等)。
  • 目前无法处理多维数组。
  • Silverlight 4.0+ 支持缺少 HashTableDataSetDataTable,因为它们不属于运行时。

市面上的其他 JSON 库

在本节中,我将讨论一些我个人使用过的 JSON 替代方案。虽然我不能说这是一个全面的列表,但它确实展示了市面上最好的产品。

XML

如果您正在使用 XML,那么别用。它太慢且臃肿了。它值得获得荣誉提名,因为它曾是每个人首先使用的东西,但说实话,别用它。它比本列表中最慢的 JSON 慢约 50 倍。优点是您可以在 JSON 和 XML 之间轻松转换。

BinaryFormatter

可能是最健壮的计算机间数据传输格式。它的性能相当不错,尽管本列表中的一些实现比它更优。

优点 缺点
  • 可以处理任何带有 Serializable 属性的类型。
  • 输出相当紧凑。
  • 版本不兼容:必须反序列化到与序列化时完全相同的类。
  • 不适合存储数据,因为它存在版本问题。
  • 不可读。
  • 不适用于平台外的通信(例如,两端都必须是 .NET)。

Json.NET

.NET 框架中最常引用的 JSON 序列化器是来自(http://JSON.codeplex.com/)的 Json.NET,其博客网站为(http://james.newtonking.com/pages/JSON-net.aspx)。这是我在自己应用程序中使用的第一个 JSON 实现。

优点 缺点
  • 输出健壮,可以处理数据集。
  • 我见过的第一个能够处理多态对象集合的实现。
  • DLL 体积大,约 320KB。
  • 与列表中其他库相比速度较慢。
  • 源代码难以理解,因为它很大。

LitJSON

我花费了大量精力才找到这个宝藏(http://litjson.sourceforge.NET/),它自 2007 年以来一直停留在 0.5 版本。在我自己的实现之前,我使用的是 LitJSON,它取代了之前的 JSON 序列化器 Json.NET。诚然,我必须修改原始代码以满足上述要求。

优点 缺点
  • (在我修改之后)可以实现 Json.NET 的所有功能。
  • DLL 体积小,约 57KB。
  • 速度相对较快。
  • 原始源代码不处理数据集(我后来在自己的应用程序中编写了相关代码)。
  • 词法分析器类难以理解。
  • 需要 .NET 3.5(我通过实现一个 Linqbridge 类来解决此限制,该类与 .NET 2.0 兼容)。

ServiceStack Serializer

Demis Bellot 开发的一个惊人的快速 JSON 序列化器,位于(http://www.servicestack.NET/mythz_blog/?p=344)。该序列化器的速度令人震惊,尽管它不支持所需的序列化功能。我在此包含它作为性能参考。

优点 缺点
  • 惊人的快速序列化器。
  • DLL 体积相当小,约 91KB。
  • 无法处理多态对象集合。
  • 至少需要 .NET 3.5。
  • 无法处理可空类型。
  • 无法处理数据集。
  • 无法处理其他“奇异”类型,如字典、哈希表等。

Microsoft Json Serializer (v1.7 更新)

应广大读者的要求,以及我之前对 Microsoft JSON 实现的无知,并感谢所有指出这一点的人,我已将其添加到此处。

优点 缺点
  • 包含在框架内。
  • 可以序列化基本的多态对象。
  • 无法反序列化多态对象。
  • 无法处理数据集。
  • 无法处理其他“奇异”类型,如字典、哈希表等。
  • 序列化速度是 fastJSON 的 4 倍。

如何使用代码

要使用代码,请执行以下操作:

// to serialize an object to string
string jsonText = fastJSON.JSON.Instance.ToJSON(c);

// to deserialize a string to an object
var newobj = fastJSON.JSON.Instance.ToObject(jsonText);

主类是 JSON,它被实现为单例,因此可以缓存类型和属性信息以提高速度。

v1.7.5 版本新增内容

// you can set the defaults for the Instance which will be used for all calls
JSON.Instance.UseOptimizedDatasetSchema = true; // you can control the serializer dataset schema
JSON.Instance.UseFastGuid = true;               // enable disable fast GUID serialization
JSON.Instance.UseSerializerExtension = true;    // enable disable the $type and $map inn the output

// you can do the same as the above on a per call basis
public string ToJSON(object obj, bool enableSerializerExtensions)
public string ToJSON(object obj, bool enableSerializerExtensions, bool enableFastGuid)
public string ToJSON(object obj, bool enableSerializerExtensions, bool enableFastGuid, bool enableOptimizedDatasetSchema)

// Parse will give you a Dictionary<string,object> with ArrayList representation of the JSON input
public object Parse(string json)

// if you have disabled extensions or are getting JSON from other sources then you must specify
// the deserialization type in one of the following ways
public T ToObject<T>(string json)
public object ToObject(string json, Type type)

v1.7.6 版本新增内容

JSON.Instance.SerializeNullValues = true;    // enable disable null values to output

public string ToJSON(object obj, bool enableSerializerExtensions, bool enableFastGuid, bool enableOptimizedDatasetSchema, bool serializeNulls)
 

v1.8 版本新增内容

对于那些询问为什么不支持类型 "X" 的用户,我已经实现了一个“开放-封闭”原则的扩展,它允许您在不修改代码的情况下实现对不支持类型的自定义例程。

要启用此扩展,您必须使用 CUSTOMTYPE 编译器指令进行编译,因为它会带来性能损失。

public void main()
{
     fastJSON.JSON.Instance.RegisterCustomType(typeof(TimeSpan), tsser, tsdes);
     // do some work as normal
}

private static string tsser(object data)
{
     return ((TimeSpan)data).Ticks.ToString();
}

private static object tsdes(string data)
{
     return new TimeSpan(long.Parse(data))
}

性能测试

所有测试均在以下计算机上运行:

  • AMD K625 1.5Ghz 处理器
  • 4GB DDR2 内存
  • Windows 7 家庭高级版 64位
  • Windows 评分 3.9

测试在三种不同的 .NET 编译版本下进行:

  • .NET 3.5
  • .NET 4,处理器类型设置为自动
  • .NET 4,处理器类型设置为 x86

下面的 Excel 截图是这些测试的结果,并附有以下说明:

  • 数字表示以毫秒为单位的经过时间。
  • 背景越,时间越
  • 背景越绿,时间越
  • 每个序列化器进行了 5 次测试。
  • "AVG" 列是最后 4 次测试的平均值,排除了第一次测试(该测试基本上是序列化器设置其内部缓存结构,因此时间不准确)。
  • "min" 行是下方相应列中的最小值。
  • Json.NET 序列化器测试了两个版本:3.5r6 和 4.0r1(当前版本)。
  • "bin" 是 BinaryFormatter 的测试,用于参考。
  • 测试结构是下面的代码,它是一个 5 次循环,内部处理 1000 个对象。
  • 已从测试数据结构中移除了一些数据类型,以便所有序列化器都能正常工作。

测试代码模板

以下是基本的测试代码模板。如您所见,它是一个包含 5 次测试的循环,其中每次测试都执行我们想要测试的操作(1000 次)。经过的时间会以制表符分隔的形式输出到控制台,您可以将其管道传输到文件,以便在 Excel 电子表格中更方便地查看。

int count = 1000;
private static void fastjson_serialize()
{
    Console.WriteLine();
    Console.Write("fastjson serialize");
    for (int tests = 0; tests < 5; tests++)
    {
        DateTime st = DateTime.Now;
        colclass c;
        string jsonText = null;
        c = CreateObject();
        for (int i = 0; i < count; i++)
        {
            jsonText = fastJSON.JSON.Instance.ToJSON(c);
        }
        Console.Write("\t" + DateTime.Now.Subtract(st).TotalMilliseconds + "\t");
    }
}

测试数据结构

测试数据是以下类,它们展示了我们要测试的多态性质。"colclass" 是这些数据结构的集合。在附加的源文件中,包含了更奇异的数据结构,如 Hashtables、Dictionaries、Datasets 等。

[Serializable()]
public class baseclass
{
    public string Name { get; set; }
    public string Code { get; set; }
}

[Serializable()]
public class class1 : baseclass
{
    public Guid guid { get; set; }
}

[Serializable()]
public class class2 : baseclass
{
    public string description { get; set; }
}

[Serializable()]
public class colclass
{
    public colclass()
    {
        items = new
List<baseclass>();
        date = DateTime.Now;
        multilineString = @"
        AJKLjaskljLA
   ahjksjkAHJKS
   AJKHSKJhaksjhAHSJKa
   AJKSHajkhsjkHKSJKash
   ASJKhasjkKASJKahsjk
        ";
        gggg = Guid.NewGuid();
        //hash = new Hashtable();
        isNew = true;
        done= true;
    }
    public bool done { get; set; }
    public DateTime date {get; set;}
    //public DataSet ds { get; set; }
    public string multilineString { get; set; }
    public List<baseclass> items { get; set; }
    public Guid gggg {get; set;}
    public decimal? dec {get; set;}
    public bool isNew { get; set; }
    //public Hashtable hash { get; set; }

} 

.NET 3.5 序列化

xxxxxxxxxxxxxxx

  • 在此测试中,fastJSON 位居第二,比 Stacks 慢了近 35%。
  • fastJSON 比 binary formatter 快近 2.9 倍。
  • Json.NET 的新版本 4.0r1 比其前一版本 3.5r6 慢了近 1.9 倍。
  • Json.NET v3.5r6 比 binary formatter 快了近 20%。

.NET 3.5 反序列化

xxxxxxxxxxxxxxx

  • 在此测试中,fastJSON 位居第一,比 Stacks 快 10%。
  • fastJSON 比其他最近的 JSON 库快近 4 倍。
  • Json.NET v4 比其前一版本 3.5r6 快了 1.5 倍。

.NET 4 自动序列化

xxxxxxxxxxxxxxx

  • 在此测试中,fastJSON 以近 20% 的优势领先 Stacks,位居第一。
  • fastJSON 比 binary formatter 快近 4.9 倍。
  • Json.NET v3.5r6 与 binary formatter 性能相当。

.NET 4 自动反序列化

xxxxxxxxxxxxxxx

  • fastJSON 以 11% 的优势领先,位居第一。
  • fastJSON 比 binary formatter 快 1.7 倍。
  • Json.NET v4 比其前一版本快 1.5 倍。

.NET 4 x86 序列化

xxxxxxxxxxxxxxx

  • 在此测试中,fastJSON 以近 21% 的优势领先 Stacks,位居第一。
  • fastJSON 比 binary formatter 快 4 倍。
  • Json.NET v3.5r6 比前一版本快 1.7 倍。

.NET 4 x86 反序列化

xxxxxxxxxxxxxxx

  • 在此测试中,fastJSON 以 5% 的优势领先 Stacks,位居第一。
  • fastJSON 比排在第三的 binary formatter 快 1.7 倍。

奇异数据类型测试

在本节中,我们将看到奇异数据类型(如数据集、哈希表、字典等)的性能结果。比较对象是 fastJSON 和 BinaryFormatter,因为大多数其他序列化器无法处理这些数据类型。其中包括:

  • 数据集
  • 可空类型
  • 哈希表
  • 字典

xxxxxxxxxxxxxxxfastJSON/exotic.png

  • fastJSON 在序列化方面比 BinaryFormatter 快 5 倍。
  • fastJSON 在反序列化方面比 BinaryFormatter 快 20%。
  • 数据集是性能杀手,会使性能降低 10 倍。

性能结论

  • 在所有测试中,fastJSON 都比其他库快,除了在 .NET 3.5 上运行序列化器时,此时 Stacks 更快,但仅快 35%(请注意,Stacks 不是多态的,无法处理所有类型,因此在测试中无法正确输出数据)。
  • .NET 4 的性能比 .NET 3.5 快约 15%,但 fastJSON 序列化器除外,它快了 90%。
  • 您可以用 fastJSON 替换 BinaryFormatter,从而获得巨大的性能提升(这种精简的方式也适合文本输出的压缩技术)。
  • fastJSON 的启动成本平均比 Stacks 快 2 倍,并且始终比其他所有库都快。

性能结论 v1.4

xxxxxxxxxxxxxxxfastJSON/v1.4.png

从上图可以看出,v1.4 的性能明显提高。速度的提升使得 fastJSON 在所有测试中都比 SerializerStack 快,即使在 .net v3.5 上也是如此。

  • fastJSON 序列化器在处理带数据集时比 binary 快 6.7 倍。
  • fastJSON 反序列化器在处理带数据集时比 binary 快 2.1 倍。
  • fastJSON 序列化器在不带数据集时比 binary 快 6.9 倍。
  • fastJSON 反序列化器在不带数据集时比 binary 快 1.6 倍。

性能结论 v1.5

xxxxxxxxxxxxxxxfastJSON/v1.5.png

  • 数字说明了一切:fastJSON 序列化器在不带数据集时快 6.65 倍,带数据集时比 binary 快 6.88 倍,反序列化器比 binary 快 2.7 倍。
  • v1.5 版本与 v1.4 版本相比,数字上的差异是由于测试中增加了枚举等属性。

性能结论 v1.6

xxxxxxxxxxxxxxxfastJSON/v1.6.png

  • 使用 Base64 编码后,Guid 的处理速度快了 2 倍。您可以通过 JSON.Instance 上的 UseFastGuid = false 来恢复到旧样式。
  • 数据集:体积缩小约 40%,速度提升约 35%。
  • fastJSON 序列化器现在的速度大约是反序列化器的 2.3 倍,极限似乎是 2 倍。

性能结论 v1.7

xxxxxxxxxxxxxxxfastJSON/v1.7.png

  • intlong 解析速度快了 4 倍。
  • Unicode 字符串优化,读取和写入非英语字符串的速度更快。
  • ChangeType 方法已优化。
  • 使用 TryGetValue 优化了 Dictionary

关注点

我使用性能分析器进行了大量的性能调优,以下是我的结果:

  • 始终使用 StringBuilder,绝不使用字符串拼接。
  • 切勿执行以下操作:stringbuilder.append("string1 + "string2"),因为它会严重影响性能,请将其替换为两个 StringBuilder append 操作。这一点让我大吃一惊,在我的性能分析器测试中,这种改动使速度提高了 50%。
  • 切勿为 StringBuilder 设置初始容量值,例如 var stringbuilder = new StringBuilder(4096);。奇怪的是,不设置容量反而更快。
  • 我尝试用 MemoryStream 替换 StringBuilder,但它太慢了(慢了 100%)。
  • 最简单、最直接的方法可能也是最快的,例如,读取值而不是使用词法分析器实现。
  • 始终使用对象上的缓存反射属性。

附录 v1.9.8

在此版本中进行了一些重新格式化,以使 fastJSON 的使用更加简便,这可能会破坏一些现有代码,但从长远来看是更好的。在此版本中使用序列化器,您可以执行以下操作:

// per call customization of the serializer
string str = fastJSON.JSON.Instance.ToJSON(obj, 
                 new fastJSON.JSONParamters { EnableAnonymousTypes = true }); // using the parameters

fastJSON.JSON.Instance.Parameters.UseExtensions = false; // set globally

这消除了许多 ToJSON 重载,使您的代码更具可读性。

同样在此版本中添加了对匿名类型的支持,这将为您提供该类型的 JSON 字符串,但目前无法反序列化,因为匿名类型是编译器生成的。

添加了 DeepCopy,它允许您创建对象的精确副本,这对于业务应用程序的回滚/取消语义非常有用。

附录 v2.0.0

终于有时间为项目添加单元测试了(主要是因为一些尴尬的错误出现在更改中),希望这些测试能覆盖大多数用例,我将来还会添加更多。

此外,根据广大用户的要求,您现在可以反序列化根级别的基本值类型、列表和字典。因此,您可以使用以下样式的代码:

var o = fastJSON.JSON.Instance.ToObject<List<Retclass>>(s); // return a generic list

var o = fastJSON.JSON.Instance.ToObject<Dictionary<Retstruct, Retclass>>(s); // return a dictionary

此版本的一个重大更改是 Parse() 方法现在将数字格式返回为 longdecimal,而不是 string 值。这对于数组返回和符合 JSON 格式是必要的(保留原始 JSON 中的类型信息,而不是丢失为字符串)。因此,以下代码现在可以工作:

List<int> ls = new List<int>();
ls.AddRange(new int[] { 1, 2, 3, 4, 5, 10 }); 
var s = fastJSON.JSON.Instance.ToJSON(ls);
var o = fastJSON.JSON.Instance.ToObject(s); // long[] {1,2,3,4,5,10}

请注意,如果您不提供类型信息,返回值将是 long 而不是 int。要获得您期望的结果,请使用以下样式的代码:

var o = fastJSON.JSON.Instance.ToObject<List<int>>(s); // you get List<int>

有关上述情况的示例代码,请查看单元测试项目。

附录 v2.0.3 - Silverlight 支持

Microsoft 凭借其无限的智慧,在 Silverlight 5 中移除了一些 Silverlight 4 中的功能。因此,fastJSON 将无法在 Silverlight 5 上构建或运行。

附录 v2.0.10 - MonoDroid 支持

在此版本中,我添加了一个 MonoDroid 项目文件,并且 fastJSON 现在可以在运行 Xamarin 的 Miguel de Icaza 及其团队开发的优秀作品的 Android 设备上构建和运行。这本应该是 Silverlight 的样子,我对此感到非常兴奋,因为它将开启许多机会,其中之一就是新的 RaptorDB

附录 v2.0.11 - Unicode 更改

 

 

我为所有因我误读 JSON 标准中关于 Unicode 的规定而道歉,我的解释是输出应为 ASCII 格式,因此所有非 ASCII 字符都应采用 \uxxxx 格式。

在此版本中,您可以通过 UseEscapedUnicode 参数控制输出格式,并且所有字符串都将采用 Unicode 格式(无 \uxxxx),默认值为 true 以保持向后兼容。

附录 - fastJSON vs Json.net 重新对比

在收到 James Newton King 要求重新测试其新版本 Json.net(版本为 v5r2)后,我重新进行了测试,结果如下(时间以毫秒为单位):

xxxxxxxxxxxxxxx

如您所见,有 5 项测试,AVG 列是最后 4 次测试的平均值,以排除每个库的启动时间;DIFF 列是两个库之间的差异,并且 fastJSON 是测试的基础。

需要注意的事项:

  • fastJSON 在序列化和反序列化方面都比 Json.net约 2 倍
  • Json.net 比其早期版本快约 1.5-2 倍,这表明其优化工作做得非常出色,值得祝贺。

附录 v2.0.17 - 动态对象

应广大用户要求,已添加对 dynamic 对象的支持,因此您可以使用 fastJSON 执行以下操作:

string s = "{\"Name\":\"aaaaaa\",\"Age\":10,\"dob\":\"2000-01-01 00:00:00Z\",\"inner\":{\"prop\":30}}";
dynamic d = fastJSON.JSON.Instance.ToDynamic(s);
var ss = d.Name;
var oo = d.Age;
var dob = d.dob;
var inp = d.inner.prop; 

附录 v2.0.28.1 - 参数化构造函数

从这个版本开始,fastJSON 现在可以处理参数化构造函数类(没有默认构造函数)的反序列化,例如:

public class pctor
{
      public pctor(int a) // pctor() does not exist
      {
      }
}

现在,为了实现这一点,fastJSON 使用了框架中的 FormatterServices.GetUninitializedObject(type),它本质上只是为您的类型分配一块内存,并将其作为对象返回,绕过了所有初始化,包括构造函数。虽然这非常快,但它有一个不幸的副作用,即忽略所有类初始化,例如属性的默认值等。因此,如果您正在恢复对象的部分数据,您应该意识到这一点(如果所有数据都在 JSON 中且与类结构匹配,那么您就没问题)。

要控制这一点,您可以在 JSONParameters 中将 ParametricConstructorOverride 设置为 true。

附录 v2.1.0 - 循环引用和重大更改

从这个版本开始,我修复了一个从一开始就一直困扰我的设计缺陷,即移除了 JSON.Instance 单例。这意味着您键入的内容更少,总是好事;坏事是您需要在代码中进行查找和替换,并且 nuget 包将不再是即插即用的,您需要使用新版本进行构建。

我还发现了一种非常简单快速的方法来支持循环引用的对象结构。因此,复杂的结构(如下所示)将能够正确地序列化和反序列化(单元测试是 CircularReferences())。

var o = new o1 { o1int = 1, child = new o3 { o3int = 3 }, o2obj = new o2 { o2int = 2 } };
o.o2obj.parent = o;
o.child.child = o.o2obj;

为此,fastJSON 将循环引用替换为:

{"$i" : number } // number is an index for the internal reference

此外,在 JSON 的顶部添加了一个 $circular : true,以便反序列化器能够识别。因此,上述结构会产生以下 JSON:

{
   "$circular" : true,
   "$types" : {
      "UnitTests.Tests+o1, UnitTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" : "1",
      "UnitTests.Tests+o2, UnitTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" : "2",
      "UnitTests.Tests+o3, UnitTests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" : "3"
   },
   "$type" : "1",
   "o1int" : 1,
   "o2obj" : {
      "$type" : "2",
      "o2int" : 2,
      "parent" : {
         "$i" : 1
      }
   },
   "child" : {
      "$type" : "3",
      "o3int" : 3,
      "child" : {
         "$i" : 2
      }
   }
}

附录 v2.1.3 - 毫秒和树莓派

经过大量要求,我已将毫秒分辨率支持添加到 DateTime 序列化中。虽然 JSON 标准没有明确说明格式,但似乎有一个普遍共识。因此,如果您启用 JSONParameters.DateTimeMilliseconds 标志,您将获得:

"2014-09-15 09:40:16.006Z"

重要提示:反序列化上述内容时,生成的 DateTime不等于原始值,因为 DateTime 对象还有一个 Tick 值,该值未被序列化,将为 0,因此对象比较将为 false

另外,我最近得到了一台 Raspberry Pi,在其上安装了 mono 并复制了 fastJSON,结果如下:

xxxxxxxxxxxxxxx

这相当令人难以置信,也说明了 mono 团队的功劳,只需将我的 DLL 文件从 Windows 系统复制过去即可工作。

作为对比,我在此下方添加了我新开发笔记本电脑(配备 i7 4702MQ 和 8GB 内存)的结果:

xxxxxxxxxxxxxxx

可以看出,Raspberry 慢了约 100 倍,但仍然可用。

附录 v2.3.5 - 解析器优化

在此版本中,解析器得到了优化,可以跳过 JSON 中存在但对象中不存在的属性。适用于您的数据来自其他地方,而您只关心其中一些属性的情况。以前,fastJSON 会解析 JSON 字符串中的所有属性,然后填充您想要的那个对象;现在,解析器更智能,会跳过不需要的属性。

此功能适用于 ToObect<T>()ToObject(string, Type) 泛型接口,您可以在其中提供结果类型。当 JSON 字符串包含 $types 定义时,它也适用于通用的非类型化情况。

为获得最大的兼容性,此功能将在涉及其他类中的 Dictionary<,> 属性的边缘情况下被禁用。

在马科斯·基尔希纳(Marcos Kirchner)提供的一个 29MB JSON 文件上进行了一些测试结果,“full”后缀表示每个库的 Deserialize<object>() 或等效功能,这确保了读取所有属性。

on dotnet 4 full framework:

          Newtonsoft    629 ms
      NewtonsoftFull  3,437 ms

                 Jil    343 ms
             JilFull  2,767 ms

                utf8    367 ms
            utf8Full  1,581 ms

            FastJson    194 ms
       FastJsonParse  1,154 ms   
on dotnet core 3.1:

          Newtonsoft :    652 ms
      NewtonsoftFull :  3,455 ms

      SystemTextJson :    412 ms
  SystemTextJsonFull :    811 ms

                 Jil :    364 ms
             JilFull :  2,988 ms

            FastJson :    283 ms
       FastJsonParse :  1,185 ms

Microsoft 的 JSON 序列化器在 .net core 上表现非常出色。fastJSON 在完整框架上的性能似乎更好,原因未知。

旧版本

您可以在此处查看 fastJSON 的先前版本。

历史

  • 初始发布 : 2011/02/20
  • 更新 v1.1:数据集反序列化性能提升 26%,修正了 ServiceStack 的名称。
  • 更新 v1.2:System.DBNull 序列化为 null,CultureInfo 数字格式修复,正确处理只读属性。
  • 更新 v1.3:移除未使用的代码(现为 780 行),属性逗号修复。
  • 更新 v1.4:大量优化(序列化器提速 3%,反序列化器提速 50%,数据集序列化器提速 46%,数据集反序列化器提速 26%)[在 .net 3.5 上,所有测试中均已正式快于 ServiceStack 序列化器]。
  • 更新 v1.5:大量优化(反序列化器比 v1.4 快约 50%),枚举修复,序列化器增加 Max Depth 属性。特别感谢 Simon Hewitt 在此版本中进行的优化。
  • 更新 v1.6 :
    • 支持值类型数组。
    • Guid 速度提升 2 倍。
    • 数据集体积缩小约 40%。
    • 序列化器速度提升约 2% 至 11%。
    • 反序列化器速度提升约 6% 至 38%。
  • 更新 v1.7 :
    • 添加了 Microsoft JSON 评估。
    • 下载中添加了 Consoletest 项目,用于测试更新的奇异类型。
    • 修复了字典反序列化错误。
    • 特殊情况处理 List<object[]>。
    • int 和 long 解析速度提升 4 倍。
    • Unicode 字符串优化。
    • ChangeType 优化。
    • 字典优化。
    • 反序列化嵌套类,例如 Sales.Customer。
    • 在添加之前进行 SafeDictionary 检查。
    • 处理 object ReturnEntity = new object[] { object1, object2 }。
    • 处理 object ReturnEntity = Guid, Dataset, valuetype。
  • 更新 v1.7.5 :
    • 能够禁用扩展进行序列化。
    • 序列化和反序列化方法重载。
    • 反序列化器会尽力反序列化输入(无论是否包含扩展),但不保证多态性。
  • 更新 v1.7.6 :
    • 处理 XmlIgnore:感谢 Patrik Oscarsson 的建议。
    • 为 string,string 字典提供特殊优化的输出。
    • 修复了年份为 1 的日期输出为 0000 字符串的错误。
    • 覆盖 null 值的序列化输出:再次感谢 Patrik。
  • 更新 v1.7.7 :
    • 缩进输出。
    • 支持 DataTable。
    • 错误修复。
  • 更新 v1.7.7 Silverlight4:2011 年 6 月 4 日。
    • 为 Silverlight 4 添加了一个新项目,目前处于测试阶段,完成后将添加到主 zip 文件中。
    • Silverlight 缺少 ArrayList、DataSet、DataTable、HashTable 支持。
    • 源文件中的 #if 语句用于 Silverlight 4 支持。
  • 更新 v1.8:2011 年 6 月 9 日。
    • Silverlight 代码已合并到项目中。
    • 单独的 Silverlight 项目。
    • 为用户定义的序列化例程添加了 RegisterCustomType 扩展。
    • CUSTOMTYPE 编译器指令。
  • 更新 v1.9:2011 年 6 月 28 日。
    • 添加了对公共字段的支持。
  • 更新 v1.9.1:2011 年 6 月 30 日。
    • 修复了 SerializeNullValues = false 时一个糟糕的错误,特别感谢 Grant Birchmeier 的测试。
  • 更新 v1.9.2:2011 年 7 月 10 日。
    • 修复了在属性缓存中搜索类型时使用全名而不是名称(namespace1.myclass, namespace2.myclass 现在是不同的),感谢 alex211b
  • 更新 v1.9.3:2011 年 7 月 31 日。
    • 通过 UseUTCDateTime = true 属性处理 UTC datetime,感谢 mrkappa
    • 添加了对字典中枚举作为键的支持,感谢 Grant Birchmeier
  • 更新 v1.9.4:2011 年 9 月 23 日。
    • 添加了 ShowReadOnlyProperties 以导出只读属性(默认 = false)。
    • 如果 datetime 值以 "Z" 结尾,则自动计算 UTC 时间。
    • 如果使用 UTC datetime,输出将以 "Z" 结尾(符合标准)。
  • 更新 v1.9.6:2011 年 11 月 26 日。
    • 修复了 DataTable 架构序列化和反序列化错误。
    • 添加了 $types 扩展用于全局类型定义,从而减小了输出 JSON 的大小,感谢 Marc Bayé 的建议。
    • 添加了 UsingGlobalTypes 配置来控制上述功能(默认为 true)。
    • 修复了 DataTable 数组和表定义之间的逗号错误(减少了 lint 警告)。
    • 字符串键字典现在被最优地序列化(不是 K V 格式)。
  • 更新 v1.9.7:2012 年 5 月 10 日。
    • 修复了 SilverLight 版本以支持 GlobalTypes。
    • 从序列化器中移除了缩进逻辑。
    • 添加了 Beautify(json) 方法到 JSON,归功于 Mark http://stackoverflow.com/users/65387/mark
    • 在 SafeDictionary 上添加了锁。
    • 添加了 FillObject(obj,json) 用于填充现有对象。
  • 更新 v1.9.8:2012 年 5 月 17 日。
    • 添加了 DeepCopy(obj) 和 DeepCopy<T>(obj)。
    • 代码重构为 JSONParameters 并移除了 JSON 重载。
    • 添加了对匿名类型序列化的支持(目前无法反序列化)。
    • 修复了根对象非 object 时的 $types 输出错误。
  • 更新 v1.9.9:2012 年 7 月 24 日。
    • JSONParameters 中的拼写错误。
    • 修复了参数初始化错误。
    • 修复了 char 和 string 的 ToString 方法。
    • 代码重构,将反射代码移至 Reflection 类。
    • 添加了对顶级结构对象序列化/反序列化的支持。
  • 更新 v2.0.0:2012 年 8 月 4 日。
    • 修复了反射代码错误。
    • 添加了单元测试。
    • 反序列化根级别数组(int[] 等)。
    • 反序列化根级别值类型(int,long,decimal,string)。
    • 反序列化 ToObject< Dictionary<T,V> >。
    • 反序列化 ToObject< List<T> >。
    • * Parse 的重大更改:数字现在返回为 decimal 和 long,而不是 string。
  • 更新 v2.0.1:2012 年 8 月 10 日。
    • 修复了 FillObject 调用时保留内部对象错误。
    • 将 ArrayList 改为 List<object> 并合并了 Silverlight 代码。
    • 添加了更多测试。
    • 使用全局类型 ($types) 时速度提升。
  • 更新 v2.0.2:2012 年 8 月 16 日。
    • 修复了 $types 和数组的错误。
  • 更新 v2.0.3:2012 年 8 月 27 日。
    • 反序列化时检查只读属性(感谢 Slava Pocheptsov)。
    • 修复了单元测试中的嵌套类型反序列化错误(感谢 Slava Pocheptsov)。
    • 修复了 Silverlight 4 项目的构建(不支持 Silverlight 5)。
  • 更新 v2.0.4:2012 年 9 月 7 日。
    • 修复了 null 对象 -> 返回 "null"。
    • 为类添加了 sealed 关键字。
    • 修复了 SerializeNullValues=false 时输出末尾有多余逗号的错误。
    • UseExtensions=false 将同时禁用全局类型(感谢 qio94donat.huttersoftwarejaeger)。
    • 修复了 Parse() 的参数设置。
  • 更新 v2.0.5:2012 年 9 月 17 日。
    • 修复了不区分区域性的数字格式解析。
    • 添加了针对德语地区数字测试(关于逗号问题)。
  • 更新 v2.0.6:2012 年 9 月 19 日。
    • 单例使用 [ThreadStatic] 实现并发(感谢 Philip Jander)。
    • 修复了当对象只有一个属性时输出多余逗号的错误(感谢 Philip Jander)。
  • 更新 v2.0.7:2012 年 10 月 5 日。
    • 修复了启用扩展时,单个属性缺少逗号的错误。
  • 更新 v2.0.8:2012 年 10 月 13 日。
    • 修复了大数字转换错误(感谢 Alex .µZ Hg.)。
    • * 重大更改:Parse 将返回 long 和 double,而不是 long 和 decimal。
    • 对值类型的 ToObject 将自动转换数据(例如 ToObject<decimal>())。
  • 更新 v2.0.9:2012 年 10 月 24 日。
    • 添加了对根级别 DataSet 和 DataTable 反序列化的支持(您需要执行 ToObject<DataSet>(...))。
    • 添加了数据集测试。
  • 更新 v2.0.10:2012 年 11 月 15 日。
    • 添加了 MonoDroid 项目。
  • 更新 v2.0.11:2012 年 12 月 7 日。
    • 修复了单个字符数字 JSON 的错误。
    • 添加了 UseEscapedUnicode 参数,用于控制字符串输出为 unicode/utf8 格式的 \uxxxx。
    • 修复了 null 和泛型 ToObject<>() 的错误。
    • 修复了自定义类型的 List<> 错误。
  • 更新 v2.0.12:2013 年 1 月 3 日。
    • 修复了嵌套泛型类型错误(感谢 Zambiorix)。
    • 修复了 null 时的逗号边缘情况。
  • 更新 v2.0.13:2013 年 1 月 9 日。
    • 修复了 null 时的逗号边缘情况。
    • 将 DynamicMethod 调用与 SilverLight 4 代码统一。
    • 添加了 Silverlight 的测试用例。
  • 文章更新:2013 年 4 月 12 日。
    • fastJSON 与 Json.net v5r2 重新对比。
  • 更新 v2.0.14:2013 年 4 月 19 日。
    • Sean Cooper 进行的优化:
      - 使用 Stopwatch 而不是 DateTime 进行计时。
      - myPropInfo 使用 enum 而不是 boolean。
      - 使用 switch 而不是链式 if 语句。
      - DateTime 解析已优化。
      - StringBuilder 使用单个字符输出而不是字符串来表示 \" 等字符。
  • 更新 v2.0.15:2013 年 5 月 24 日。
    • 移除了代码中的 CUSTOMTYPE 指令。
    • 修复了写入可枚举对象的问题。
  • 更新 v2.0.16:2013 年 6 月 22 日。
    • 修复了 formatter 错误。
    • 添加了 formatter 的测试。
  • 更新 v2.0.17:2013 年 7 月 22 日。
    • 添加了静态字段和属性的序列化。
    • 添加了动态对象支持和测试。
    • 重新格式化了文章。
  • 更新 v2.0.18:2013 年 8 月 19 日。
    • 边缘情况:空数组反序列化 "[]" -> T[]。
    • 代码清理
    • 修复了序列化只读属性。
  • 更新 v2.0.19:2013 年 8 月 27 日。
    • 修复了动态对象和列表(感谢 M.Killer)。
    • 修复了反序列化 Dictionary<T, List<V>>Dictionary<T, V[]>(感谢 Pelle Penna)。
    • 添加了带列表的字典测试。
  • 更新 v2.0.20:2013 年 9 月 11 日。
    • 修复了哈希表反序列化。
    • 添加了哈希表测试。
    • 添加了抽象类测试。
    • 将 getter 列表更改为数组,性能提升约 3%。
    • 移除了未使用的代码。
  • 更新 v2.0.21:2013 年 9 月 18 日。
    • 修复了 formatter 中末尾的反斜杠边缘情况。
    • 清理了 formatter 代码。
  • 更新 v2.0.22:2013 年 10 月 1 日。
    • 添加了 .net 3.5 项目。
    • 现在编译到 'output' 目录。
    • 添加了已签名的程序集。
    • 版本号将保持为 2.0.0.0 以便即插即用兼容。
    • 文件版本将反映生成号。
    • 修复了未定义类型时反序列化到字典而不是数据集的错误。
  • 更新 v2.0.23:2013 年 10 月 28 日。
    • JSONParameters.IgnoreCaseOnDeserialize 现在有效。
    • 添加了忽略大小写的测试。
  • 更新 v2.0.24:2013 年 11 月 2 日。
    • 在动态类型中访问数组的内部属性,例如 d.arr[1].a(感谢 Greg Ryjikh)。
    • 添加了 JSONParameters.KVStyleStringDictionary 来控制字符串键字典的输出。
  • 更新 v2.0.25:2013 年 11 月 16 日。
    • 修复了动态 JSON 和根数组(例如 [1,2,3,4])的错误。
  • 更新 v2.0.26:2013 年 11 月 23 日。
    • 修复了数组中对象的动态类型错误,例如 [1,2,{"prop":90}]。
    • 增加了对特殊集合的支持:StringDictionaryNameValueCollection
  • 更新 v2.0.27:2014 年 1 月 8 日。
    • 添加了 UseValuesOfEnums 参数来控制枚举输出。
    • 修复了处理 const 属性和字段(即忽略)的问题。
  • 更新 v2.0.28:2014 年 3 月 22 日。
    • 在解析器中移除了 ToCharArray,以减少内存使用(感谢 Simon Hewitt)。
    • 修复了从值和字符串创建枚举。
    • 将部分内部使用的 SafeDictionary 替换为 Dictionary,因此读取时没有锁。
    • 添加了自定义忽略属性(感谢 Jared Thirsk)。
    • 使用 IsDefined 而不是 GetCustomAttributes(感谢 Andrew Rissing)。
    • 将所有反射代码移出 JSON.cs。
    • 现在您可以反序列化非默认构造函数类(感谢 Anton Afanasyev)。
  • 更新 v2.0.28.1:2014 年 3 月 29 日。
    • 添加了 ParametricConstructorOverride 参数以控制非默认构造函数。
    • 修复了与 StructTest 运行时冲突的问题。
    • 添加了对象创建性能测试。
  • 更新 v2.1.0:2014 年 4 月 7 日。
    • *重大运行时更改*:移除了 JSON.Instance 单例。
    • 将 JSON 中的所有状态移至 Reflection 单例。
    • JSON 接口现在全部为静态。
    • 为 ToObject() 添加了 JSONParameters 重载。
    • 支持循环引用的对象结构。
    • 添加了循环引用测试。
    • 修复了 .net35 项目文件以正确编译。
  • 更新 v2.1.1:2014 年 4 月 27 日。
    • 修复了 obj.List<List<object>>obj.List<object[]> 的错误。
    • 为方法添加了代码 IntelliSense 帮助。
    • 添加了 ClearReflectionCache() 以重置所有内部结构。
  • 更新 v2.1.2:2014 年 8 月 16 日。
    • 修复了循环引用错误(感谢 SonicThg)。
  • 更新 v2.1.3:2014 年 9 月 15 日。
    • 添加了对 DateTime 毫秒的支持。
    • 添加了 TestMilliseconds() 测试。
  • 更新 v2.1.4:2014 年 10 月 6 日。
    • 修复了反序列化类中的结构属性的错误。
  • 更新 v2.1.5:2014 年 10 月 23 日。
    • 添加了直接可空类型转换 ToObject<x?>(例如 int? long? 等)(感谢 goroth)。
    • 修复了反序列化私有设置和无设置属性的错误。
    • 添加了 ReadonlyTest() 测试以处理上述情况。
  • 更新 v2.1.6:2014 年 11 月 20 日。
    • 修复了 net4 的发布版本(感谢 Craig Minihan)。
    • 支持 net4 中的 ExpandoObject 序列化(感谢 Craig Minihan)。
    • 添加了 JSONParameters.SerializerMaxDepth 以控制递归深度。
    • 添加了 JSONParameters.InlineCircularReferences 以禁用 $i 功能并内联已见对象。
    • JSONParameters.UseExtensions = false 也会禁用循环引用。
  • 更新 v2.1.7:2014 年 11 月 29 日。
    • 严格符合 ISO8601 日期格式,输出包含 T(IE、firefox JavaScript 引擎曾抱怨)。
    • 添加了 JSONParameters.SerializeToLowerCaseNames 以便与 JavaScript 互操作。
    • JSONParameters.IgnoreCaseOnDeserialize 已弃用,不再需要。
    • 添加了小写输出的测试。
    • 内部代码清理。
  • 更新 v2.1.8:2015 年 1 月 8 日。
    • 修复了序列化 static 字段和属性的错误。
    • 跳过对象的索引器属性(感谢 scymen)。
    • JSONParameters.SerializeToLowerCaseNames 也处理 DictionaryNameValueCollection
  • 更新 v2.1.9:2015 年 1 月 16 日。
    • JSONParameters.SerializeNullValues = false 正确处理 DictionaryNameValueCollection
  • 更新 v2.1.10:2015 年 2 月 24 日。
    • 修复了 byte[] 作为 Dictionary 键的错误(感谢 Stanislav Lukeš)。
  • 更新 v2.1.11:2015 年 3 月 6 日。
    • 修复了 public static properties 的错误。
  • 更新 v2.1.12:2015 年 4 月 27 日。
    • 支持多维数组(感谢 wmjordan)。
  • 更新 v2.1.13:2015 年 5 月 17 日。
    • 代码加速(感谢 wmjordan)。
  • 更新 v2.1.14:2015 年 5 月 31 日。
    • dynamic 对象处理增强(感谢 Justin Dearing)。
  • 更新 v2.1.15:2016 年 3 月 15 日。
    • 清理 usings。
    • 错误修复:边缘情况 CreateArray() 的 bt 为 null -> 默认为 typeof(object)
  • 更新 v2.1.16:2016 年 6 月 19 日。
    • 修复了 ToObject<Dictionary<string, List<X>>>() 的错误(感谢 sleiN13)。
    • 修复了 CreateStringKeyDictionary() 的错误(感谢 John Earnshaw)。
    • 类型访问优化。
    • 测试重构。
  • 更新 v2.1.17:2016 年 7 月 15 日。
    • 增加了对读取 JSON 字符串中的行注释的支持(例如 //comment)。
    • 修复了损坏的自定义类型处理程序(抱歉各位)。
    • 添加了自定义类型的测试。
    • 自动将 string 转换为 intlong,如果接收类型需要。
    • 根据需要自动转换 byte[](感谢 Enrico Padovani)。
    • 修复了匿名类型中 DateTime 导致的 InvalidProgramException(感谢 skottmckay)。
    • ExpandoObject 工作正常。
    • JSON.ToObject<T[]>() 工作正常。
    • 支持 double.NaN float.NaN,并附带测试。
    • 处理带引号的属性/字段/键名等。
    • 修复了 Dictionary 值中的 byte[],并附带测试。
    • 添加了 Twitter 数据测试。
    • 支持 DateTimeOffset
  • 更新 v2.1.18:2016 年 7 月 23 日。
    • 修复了只读属性输出的错误。
    • 添加了只读属性的测试。
    • 同步 reflection.csfastBinaryJSON
    • NonSerialized 添加到忽略默认属性列表中。
  • 更新 v2.1.19:2016 年 9 月 3 日。
    • 添加了带默认参数的 ToNiceJSON(obj)
    • 支持接口对象属性(感谢 DrDeadCrash)。
  • 更新 v2.1.20:2016 年 9 月 12 日。
    •  修复了嵌套字典 D<,D<,>> 的错误。
  • 更新 v2.1.21:2016 年 10 月 21 日。
    • 修复了枚举动态对象的错误。
  • 更新 v2.1.22:2016 年 12 月 29 日。
    • 修复了关闭扩展时 ToObject<Dictionary<string,List<T>>() 的错误(感谢 chunlizh)。
    • 添加了 Howto.md(正在进行中)。
    • 重命名了解决方案文件。
  • 更新 v2.1.23:2017 年 2 月 15 日。
    • 添加了对 TimeSpan 的支持(等同于 long)。
    • 添加了自动将字符串数字 "42" 转换为 42。
    • 向 Howto.md 添加了更多内容。
  • 更新 v2.1.24:2017 年 6 月 1 日。
    • 支持 ISO8601 格式的 DateTimeOffset(感谢 Scott McKay)。
    • 关于 $type 用法的安全警告。
  • 更新 v2.1.25:2017 年 7 月 24 日。
    • 支持 DataMember[Name] 属性。
    • 即使没有扩展,也能处理字符串中的 \0 并将其转换为 \u0000。
  • 更新 v2.1.26:2017 年 8 月 12 日。
    • 修复了 DataTable 列中 byte[] 的支持错误(感谢 HKatura)。
    • 添加了 JSONParameters.FormatterIndentSpaces
    • 修复了 float/decimal/double/long/ulong/int/uint 的边缘情况错误。
        MinValue, MaxValue, NegativeInfinity, PositiveInfinity, Epsilon, NaN(感谢 qaqz111)。
  • 更新 v2.1.27:2017 年 9 月 15 日。
    • 修复了 DataMember 属性中的大小写错误(感谢 Elvis Lam)。
    • 添加了 ToObject(string json, Type type, JSONParameters par)
    • 修复了 .net v2.0+ 使用条件编译构建的错误。
  • 更新 v2.1.28:2018 年 1 月 16 日。
    • 修复了带类型信息的对象数组反序列化的错误。
    • 为上述情况添加了测试。
    • 通过单独的项目支持 .net core 和 netstandard2.0。
  • 更新 v2.1.29:2018 年 5 月 4 日。
    • 添加了 JSONParameters.AllowNonQuotedKeys 以支持非标准的类 JavaScript JSON。
    • 签名了 .net core 和 standard 程序集。
  • 更新 v2.1.31:2018 年 5 月 9 日。
    • 反序列化时自动转换为字符串(如果对象属性是字符串且 JSON 值不是)。
    • 修复了在类中更改 JSONParameters.UsingGlobalTypes 并影响原始值的副作用。
    • 修复了在没有扩展的情况下反序列化嵌套 Dictionary(使用泛型 ToObject<>)。
  • 更新 v2.1.32:2018 年 5 月 26 日。
    • 支持非公共 setter / 只读属性(感谢 rbeurskens)。
    • 统一了 reflection.csfastBinaryJSON
  • 更新 v2.1.33:2018 年 6 月 18 日。
    • 支持不区分大小写的 enum(感谢 AgentFire)。
    • 自动转换为 boolean(数字 >0,字符串:1、true、yes、on)。
    • 修复了 .net 3.5 项目的输出框架版本。
  • 更新 v2.1.34:2018 年 6 月 28 日。
    • 能够创建内部/私有对象(移除了对类的公共访问限制)。
  • 更新 v2.1.36:2018 年 8 月 8 日。
    • 优化调整(反序列化速度提升约 30%)。
    • 将内部 tolower 改为 tolowerinvariant
    • 修复了内部 JSON 解析器中的字符指针。
    • 内部反射 struct 改为 class
  • 更新 v2.2.0:2018 年 8 月 23 日。
    • 修复了 JSON 解析器,当字符串没有指数时创建一个 decimal 数字。
    • 修复了快速创建没有容量构造函数的列表。
    • 统一了 Reflection.cs。
    • * 如果使用 RegisterCustomType(),则有运行时运行时更改 *。
  • 更新 v2.2.2:2019 年 3 月 17 日。
    • 线程安全的 JSON 格式化器(感谢 Ondrej Medek)。
    • 添加了 JSONParameters.AutoConvertStringToNumbers 以控制自动转换,如果设置为 false,则会引发异常。
    • 修复了 Linux 上 nuget 包中的文件名。
  • 更新 v2.2.3:2019 年 5 月 4 日。
    • 修复了关闭扩展时反序列化 Dictionary<int,List<X>> 的错误(感谢 Ondrej Medek)。
    • 修复了反序列化 Dictionary<int,X[]> 的错误。
  • 更新 v2.2.4:2019 年 6 月 8 日。
    • 优化了 CreateLong()CreateInteger()(感谢 djmarcus)。
    • 使 JSONParameters.MakeCopy() 公开。
  • 更新 v2.3.0:2019 年 10 月 26 日。
    • 修复了读取 int[] 中的负数的错误。
    • 修复了 JSONParameters.OverrideObjectHashCodeChecking 的对象相等性哈希码检查错误(感谢 MTantos1)。
    • 添加了 JSONParameters.BlackListTypeChecking(默认为 true,用于 Friday 13th JSON 攻击检查)。
  • 更新 v2.3.3:2020 年 9 月 29 日。
    • 从代码中移除了种族主义词语。
    • 添加了 fastSJON.DataMember 属性以支持 .net v2+。
  • 更新 v2.3.5:2020 年 10 月 20 日。
    • 优化了解析器,以便在提供类型且 JSON 中没有 $types 时进行跳过。
  • 更新 v2.3.5.1:2020 年 10 月 21 日。
    • 为测试项目添加了 nunit 的 nuget 包。
    • 代码清理
  • 更新 v2.3.5.2:2020 年 10 月 30 日。
    • 修复了解析递归对象结构时的无限循环错误。
  • 更新 v2.3.5.3:2020 年 11 月 10 日。
    • 修复了 BuildLookup() 的错误。
  • 更新 v2.4.0.2:2021 年 1 月 23 日。
    • dotnet 5.0 构建。
    • debug 和 release 配置正常工作。
    • json5 支持。
        (nan、infinity、前导/尾随小数点、尾随逗号、字符串转义、单引号/双引号。
         正/负前缀、注释、十六进制数字、多行字符串断裂)。
    • 修复了 json5 的换行错误。
    • 支持 json5 +NaN -NaN。
    • 长度超过 32 个字符的数字将被视为 double。
© . All rights reserved.