问题
When serializing the object below, Json.Net detects a self-referencing loop and throws an exception.
The class has two important features:
- it has a self-referential property,
Child
- it overrides
Equals()
andGetHashCode()
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
It appears that Json.Net uses the override of Equals()
to detect the reference loop (confirmed by debugging). But there is no loop here.
Why doesn't it use reference equality to check for a reference loop?
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.
回答1:
Newtonsoft explicitly addressed this question in Issue #401: Object reference equality should be used when checking for circular references:
I prefer the current behavior which lets devs customize logic by overriding Equals.
Besides, this is a big breaking change.
But then later added:
Added EqualityComparer to JsonSerializer 3cc797c.
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.
来源:https://stackoverflow.com/questions/46936395/why-doesnt-reference-loop-detection-use-reference-equality