当前位置: 首页> 汽车> 新车 > 免费企业静态网站模板_中国商业数据网_长沙网络推广小公司_免费奖励自己的网站

免费企业静态网站模板_中国商业数据网_长沙网络推广小公司_免费奖励自己的网站

时间:2025/7/9 2:01:30来源:https://blog.csdn.net/qq_39847278/article/details/147062135 浏览次数: 0次
免费企业静态网站模板_中国商业数据网_长沙网络推广小公司_免费奖励自己的网站

总目录


一、什么是 ReferenceHandling

1. 概述

ReferenceHandlingSystem.Text.Json 中用于处理对象引用(循环引用或重复引用)的选项。它允许开发者在序列化和反序列化时控制如何处理对象之间的引用关系。

默认情况下,System.Text.Json 不支持循环引用或重复引用的处理,直接序列化会导致堆栈溢出或数据丢失。通过启用 ReferenceHandling,可以解决以下问题:

  1. 循环引用:对象 A 引用对象 B,对象 B 又引用对象 A。
  2. 重复引用:多个属性引用同一个对象实例。

2. ReferenceHandling 的两种模式

ReferenceHandling 提供了两种模式:

  • Preserve 模式:保留对象引用,使用 $id$ref 标记引用关系。
  • IgnoreCycles 模式:忽略循环引用,避免堆栈溢出。

3. 使用场景

  • 循环引用:例如,树形结构或双向关联的对象。
  • 重复引用:例如,多个属性引用同一个对象实例。
  • 复杂对象图:需要完整保留对象引用关系的场景。

二、如何使用ReferenceHandling

1. 循环引用(Preserve 模式)

假设我们有一个简单的类,包含循环引用:

public class Node
{public string Name { get; set; }public Node Next { get; set; }
}// 创建循环引用
var nodeA = new Node { Name = "NodeA" };
var nodeB = new Node { Name = "NodeB" };
nodeA.Next = nodeB;
nodeB.Next = nodeA;// 配置 JsonSerializerOptions
var options = new JsonSerializerOptions
{ReferenceHandler = ReferenceHandler.Preserve, // 保留引用WriteIndented = true                         // 美化输出
};// 序列化
string json = JsonSerializer.Serialize(nodeA, options);
Console.WriteLine(json);

输出结果

{"$id": "1","Name": "NodeA","Next": {"$id": "2","Name": "NodeB","Next": {"$ref": "1"}}
}

解释

  • $id:唯一标识对象实例。
  • $ref:引用其他对象实例。

2. 循环引用(IgnoreCycles 模式)

如果不想保留引用关系,可以选择忽略循环引用:

var options = new JsonSerializerOptions
{ReferenceHandler = ReferenceHandler.IgnoreCycles, // 忽略循环引用WriteIndented = true                             // 美化输出
};// 序列化
string json = JsonSerializer.Serialize(nodeA, options);
Console.WriteLine(json);

输出结果

{"Name": "NodeA","Next": {"Name": "NodeB","Next": null}
}

解释

  • 循环引用的部分被设置为 null,避免堆栈溢出。

3. 重复引用

假设我们有一个对象被多个属性引用:

public class Employee
{public string Name { get; set; }public Employee Manager { get; set; }
}// 创建重复引用
var manager = new Employee { Name = "Alice" };
var employee = new Employee { Name = "Bob", Manager = manager };
manager.Manager = manager; // 自己是自己的经理// 配置 JsonSerializerOptions
var options = new JsonSerializerOptions
{ReferenceHandler = ReferenceHandler.Preserve, // 保留引用WriteIndented = true                         // 美化输出
};// 序列化
string json = JsonSerializer.Serialize(employee, options);
Console.WriteLine(json);

输出结果

{"$id": "1","Name": "Bob","Manager": {"$id": "2","Name": "Alice","Manager": {"$ref": "2"}}
}

解释

  • $id$ref 确保重复引用不会导致无限递归。

4. 反序列化(Preserve 模式)

反序列化时,ReferenceHandler.Preserve 会自动恢复对象引用关系。

var json = @"
{""$id"": ""1"",""Name"": ""Bob"",""Manager"": {""$id"": ""2"",""Name"": ""Alice"",""Manager"": {""$ref"": ""2""}}
}";var options = new JsonSerializerOptions
{ReferenceHandler = ReferenceHandler.Preserve // 保留引用
};var employee = JsonSerializer.Deserialize<Employee>(json, options);// 验证引用关系
Console.WriteLine(employee.Name);           // 输出:Bob
Console.WriteLine(employee.Manager.Name);   // 输出:Alice
Console.WriteLine(employee.Manager.Manager == employee.Manager); // 输出:True

解释

  • 反序列化后,Manager 的引用关系正确恢复。

三、注意事项

  1. 性能开销
    • 启用 ReferenceHandler.Preserve 会增加一定的性能开销,因为需要维护 $id$ref
  2. 兼容性
    • 并非所有 JSON 解析器都支持 $id$ref,需确保目标系统兼容。
  3. 默认行为
    • 默认情况下,System.Text.Json 不支持循环引用,必须显式启用 ReferenceHandler

结语

回到目录页:C#/.NET 知识汇总
希望以上内容可以帮助到大家,如文中有不对之处,还请批评指正。


参考资料:

  • .NET 官方文档:ReferenceHandler
  • System.Text.Json 完全指南
关键字:免费企业静态网站模板_中国商业数据网_长沙网络推广小公司_免费奖励自己的网站

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: