为什么引用循环检测不使用引用相等性? [英] Why doesn't reference loop detection use reference equality?

查看:102
本文介绍了为什么引用循环检测不使用引用相等性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

序列化下面的对象时,Json.Net检测到一个自引用循环并引发异常.

When serializing the object below, Json.Net detects a self-referencing loop and throws an exception.

该类具有两个重要功能:

The class has two important features:

  • 它具有自引用属性Child
  • 它会覆盖Equals()GetHashCode()
  • it has a self-referential property, Child
  • it overrides Equals() and GetHashCode()
public class Foo
{
    public int Value { get; set; }

    public Foo Child { get; set; }

    public override bool Equals(object obj) => (obj as Foo).Value == this.Value;

    public override int GetHashCode() => this.Value.GetHashCode();
}

...

var foo = new Foo { Value = 42, Child = new Foo { Value = 42 } };
JsonConvert.SerializeObject(foo); // Throws JsonSerializationException

似乎Json.Net使用Equals()的替代来检测参考循环(已通过调试确认).但是这里没有循环.

It appears that Json.Net uses the override of Equals() to detect the reference loop (confirmed by debugging). But there is no loop here.

为什么不使用 reference 相等性检查参考循环?

Why doesn't it use reference equality to check for a reference loop?

我找到了测试表明可以提供另一种使用引用相等的EqualityComparer,但是我很想知道为什么这不是默认行为.

I found a test demonstrating that one can supply a different EqualityComparer which does use reference equality, but I'm interested to know why that isn't the default behaviour.

推荐答案

Newtonsoft在

Newtonsoft explicitly addressed this question in Issue #401: Object reference equality should be used when checking for circular references:

我更喜欢当前的行为,该行为使开发人员可以通过覆盖Equals来自定义逻辑.

I prefer the current behavior which lets devs customize logic by overriding Equals.

此外,这是一个重大突破.

Besides, this is a big breaking change.

但是后来又添加了:

将EqualityComparer添加到JsonSerializer 3cc797c .

此增强功能增加了对 JsonSerializerSettings.EqualityComparer 的支持.调用 object.Equals 参考回路检测中的设置将被覆盖:

This enhancement added support for JsonSerializerSettings.EqualityComparer which allows the default behavior of calling object.Equals in reference loop detection to be overridden in settings:

public IEqualityComparer EqualityComparer { get; set; }

获取或设置序列化程序在比较引用时使用的相等比较器.

Gets or sets the equality comparer used by the serializer when comparing references.

这篇关于为什么引用循环检测不使用引用相等性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆