-
Notifications
You must be signed in to change notification settings - Fork 4.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add option to ignore reference cycles on serialization (#46101)
* Add option to ignore reference cycles on serialization * Fix whitespace * Combine IsValueType check on WriteCoreAsObject * Add missing null-forgiving operator * Fix perf regression by using ReferenceHandlerStrategy field in JsonSerializerOptions * Address suggestions * Rename API to IgnoreCycles * Add missing letter to test class name * Fix CI issue with nullable annotation
- Loading branch information
Showing
20 changed files
with
652 additions
and
44 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
12 changes: 12 additions & 0 deletions
12
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/IgnoreReferenceHandler.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
namespace System.Text.Json.Serialization | ||
{ | ||
internal sealed class IgnoreReferenceHandler : ReferenceHandler | ||
{ | ||
public IgnoreReferenceHandler() => HandlingStrategy = ReferenceHandlingStrategy.IgnoreCycles; | ||
|
||
public override ReferenceResolver CreateResolver() => new IgnoreReferenceResolver(); | ||
} | ||
} |
42 changes: 42 additions & 0 deletions
42
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/IgnoreReferenceResolver.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Collections.Generic; | ||
using System.Diagnostics; | ||
|
||
namespace System.Text.Json.Serialization | ||
{ | ||
internal sealed class IgnoreReferenceResolver : ReferenceResolver | ||
{ | ||
// The stack of references on the branch of the current object graph, used to detect reference cycles. | ||
private Stack<ReferenceEqualsWrapper>? _stackForCycleDetection; | ||
|
||
internal override void PopReferenceForCycleDetection() | ||
{ | ||
Debug.Assert(_stackForCycleDetection != null); | ||
_stackForCycleDetection.Pop(); | ||
} | ||
|
||
internal override bool ContainsReferenceForCycleDetection(object value) | ||
=> _stackForCycleDetection?.Contains(new ReferenceEqualsWrapper(value)) ?? false; | ||
|
||
internal override void PushReferenceForCycleDetection(object value) | ||
{ | ||
var wrappedValue = new ReferenceEqualsWrapper(value); | ||
|
||
if (_stackForCycleDetection is null) | ||
{ | ||
_stackForCycleDetection = new Stack<ReferenceEqualsWrapper>(); | ||
} | ||
|
||
Debug.Assert(!_stackForCycleDetection.Contains(wrappedValue)); | ||
_stackForCycleDetection.Push(wrappedValue); | ||
} | ||
|
||
public override void AddReference(string referenceId, object value) => throw new InvalidOperationException(); | ||
|
||
public override string GetReference(object value, out bool alreadyExists) => throw new InvalidOperationException(); | ||
|
||
public override object ResolveReference(string referenceId) => throw new InvalidOperationException(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
src/libraries/System.Text.Json/src/System/Text/Json/Serialization/ReferenceEqualsWrapper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Licensed to the .NET Foundation under one or more agreements. | ||
// The .NET Foundation licenses this file to you under the MIT license. | ||
|
||
using System.Runtime.CompilerServices; | ||
|
||
namespace System.Text.Json.Serialization | ||
{ | ||
internal struct ReferenceEqualsWrapper : IEquatable<ReferenceEqualsWrapper> | ||
{ | ||
private object _object; | ||
public ReferenceEqualsWrapper(object obj) => _object = obj; | ||
public override bool Equals(object? obj) => obj is ReferenceEqualsWrapper otherObj && Equals(otherObj); | ||
public bool Equals(ReferenceEqualsWrapper obj) => ReferenceEquals(_object, obj._object); | ||
public override int GetHashCode() => RuntimeHelpers.GetHashCode(_object); | ||
} | ||
} |
Oops, something went wrong.