热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

为什么Json.Net在序列化时会在我的对象上调用Equals方法?

如何解决《为什么Json.Net在序列化时会在我的对象上调用Equals方法?》经验,为你挑选了1个好方法。

我在使用Newtonsoft.Json SerializeObject方法时遇到了一个错误.之前有人问过这个问题,但与Newtonsoft合作的人没有回答为什么会这样.

基本上,这样打电话时SerializeObject:

string json = Newtonsoft.Json.JsonConvert.SerializeObject(from, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });

Equals在我的类中覆盖了很多方法中的错误:

public override bool Equals(object obj)
{
    if (obj == null)
        return false;

    CapacityConfiguration cc = (CapacityConfiguration)obj; // <-- TypeCastException here; other Properties of the same class are sent in as parameter!
}

当然,通过这样检查,我意识到修复起来很"容易":

public override bool Equals(object obj)
{
    if (obj is CapacityCOnfiguration== false)
        return false;

    CapacityConfiguration cc = (CapacityConfiguration)obj;
}

但真正的问题是: 为什么Json.Net在类的Equals方法中发送其他类型的对象?更具体地说,Json.Net似乎在类中发送了许多其他属性,而不是相同类型的另一个对象.

对我来说,这完全是奇怪的.任何输入将不胜感激.

我根据Visual Studio使用"Version 8.0.0.0".

更新1

它很容易测试,因为它是可重复的:

public class JsonTestClass
{
    public string Name { get; set; }
    public List MyIntList { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;

        JsonTestClass jtc = (JsonTestClass)obj;
        return true;
    }
}

然后将此代码放在Program.cs或其他任何地方:

JsonTestClass c = new JsonTestClass();
c.Name = "test";
c.MyIntList = new List();
c.MyIntList.Add(1);

string json = Newtonsoft.Json.JsonConvert.SerializeObject(c, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });

你会得到TypeCast异常:

在此输入图像描述



1> D-Shih..:

为什么JsonConvert.SerializeObject会调用该object.Equals方法?

因为在使用时JsonConvert.SerializeObject,会调用CheckForCircularReference方法来检查属性是否重新引用自己的对象,从而导致无限循环.

 private bool CheckForCircularReference(JsonWriter writer, object value, JsonProperty property, JsonContract contract, JsonContainerContract containerContract, JsonProperty containerProperty)

在该CheckForCircularReference方法中,部分代码使用该Contains方法,object.Equals如果您object没有实现 IEquatable接口,则会调用该方法.

bool exists = (Serializer._equalityComparer != null)
                ? _serializeStack.Contains(value, Serializer._equalityComparer)
                : _serializeStack.Contains(value);

说明

    _serializeStack 是当前正在序列化的对象列表.

    List.Contains方法检查集合中是否包含当前属性.

    List.Contains使用EqualityComparer.Default,IEquatable如果类型实现它,则使用,object.Equals否则.

    object value参数是您当前的Property对象.


以下是自引用循环的示例:

public class JsonTestClass
{
    public string Name { get; set; }
    public List MyIntList { get; set; }
    public JsonTestClass Test{get;set;}
    public override bool Equals(object obj)
    {
        if (obj == null)
            return false;
        JsonTestClass jtc = (JsonTestClass)obj;
        return true;
   }
}

JsonTestClass c = new JsonTestClass();
c.Name = "test";
c.Test = c;
string json = JsonConvert.SerializeObject
               (c, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });

我们会得到一个例外:

使用类型"Program + JsonTestClass"检测属性"test"的自引用循环.路径''.

但如果我们这样做就没有错误:

JsonTestClass c = new JsonTestClass();
c.Name = "test";
c.Test = new JsonTestClass();

string json = JsonConvert.SerializeObject
       (c, new JsonSerializerSettings() { TypeNameHandling = TypeNameHandling.All });


好吧,所以这是设计然后.对我来说足够好了.
推荐阅读
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • ASP.NET2.0数据教程之十四:使用FormView的模板
    本文介绍了在ASP.NET 2.0中使用FormView控件来实现自定义的显示外观,与GridView和DetailsView不同,FormView使用模板来呈现,可以实现不规则的外观呈现。同时还介绍了TemplateField的用法和FormView与DetailsView的区别。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • JDK源码学习之HashTable(附带面试题)的学习笔记
    本文介绍了JDK源码学习之HashTable(附带面试题)的学习笔记,包括HashTable的定义、数据类型、与HashMap的关系和区别。文章提供了干货,并附带了其他相关主题的学习笔记。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • iOS超签签名服务器搭建及其优劣势
    本文介绍了搭建iOS超签签名服务器的原因和优势,包括不掉签、用户可以直接安装不需要信任、体验好等。同时也提到了超签的劣势,即一个证书只能安装100个,成本较高。文章还详细介绍了超签的实现原理,包括用户请求服务器安装mobileconfig文件、服务器调用苹果接口添加udid等步骤。最后,还提到了生成mobileconfig文件和导出AppleWorldwideDeveloperRelationsCertificationAuthority证书的方法。 ... [详细]
author-avatar
黄于諭春琪
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有