为什么不参考循环检测使用引用相等?

时间:2017-10-25 15:27:50

标签: c# json.net

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

该课程有两个重要特征:

  • 它具有自引用属性Child
  • 它会覆盖Equals()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()的覆盖来检测参考循环(通过调试确认)。但这里没有循环。

为什么不使用引用相等来检查引用循环?

我发现a test证明可以提供使用引用相等的不同EqualityComparer,但我很想知道为什么这不是默认行为。

1 个答案:

答案 0 :(得分:2)

Newtonsoft在 Issue #401: Object reference equality should be used when checking for circular references

中明确地解决了这个问题
  

我更喜欢当前的行为,它允许开发人员通过重写Equals来定制逻辑。

     

此外,这是一个重大变化。

但后来补充道:

  

将EqualityComparer添加到JsonSerializer 3cc797c

此增强功能添加了对JsonSerializerSettings.EqualityComparer的支持,允许在设置中覆盖参考循环检测中调用object.Equals的默认行为:

  

public IEqualityComparer EqualityComparer { get; set; }

     

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