Class ReferenceTracker
Tracks object references during serialization and deserialization to detect cyclic graphs and, optionally, preserve object identity across the serialized representation.
Inherited Members
Namespace: Scylla.Core.Util.Serialization
Assembly: ScyllaCore.dll
Syntax
public sealed class ReferenceTracker
Remarks
ReferenceTracker uses reference identity (pointer equality via GetHashCode(object)) rather than value equality to distinguish objects. This means two objects that are structurally equal but distinct instances are tracked independently.
During serialization: Call TryTrack(object, out int) before recursing into
each object. If the method returns true, a cycle has been detected and the
returned referenceID can be emitted as a back-reference
instead of re-serializing the full object. The behavior on cycle detection
(throw, emit a back-reference, or serialize as null) is governed by
Handling.
During deserialization: Call Register(int, object) immediately after constructing each object so that back-references (resolved via TryResolve(int, out object)) can be patched in when the serialized data refers to a previously seen ID.
A single ReferenceTracker instance should be created per serialization or deserialization operation and then discarded. Call Clear() if the same instance needs to be reused across multiple independent operations.
Constructors
ReferenceTracker(ReferenceHandling)
Initializes a new ReferenceTracker with the specified cycle-handling strategy.
Declaration
public ReferenceTracker(ReferenceHandling handling)
Parameters
| Type | Name | Description |
|---|---|---|
| ReferenceHandling | handling | Determines what action the serialization engine takes when a cyclic reference is detected via TryTrack(object, out int). The tracker itself does not enforce the strategy - it is the caller's responsibility to consult Handling and respond accordingly. |
Properties
Count
Gets the total number of objects currently tracked by this instance.
Declaration
public int Count { get; }
Property Value
| Type | Description |
|---|---|
| int | The number of entries in the forward Scylla.Core.Util.Serialization.ReferenceTracker._objectToID dictionary.
Incremented by TryTrack(object, out int) on each newly seen object, and reset to
|
Handling
Gets the ReferenceHandling strategy this tracker was configured with.
Declaration
public ReferenceHandling Handling { get; }
Property Value
| Type | Description |
|---|---|
| ReferenceHandling | One of Error, Preserve, or Ignore. This value does not change after construction; consult it alongside the return value of TryTrack(object, out int) to decide how the serialization engine should respond to a detected cycle. |
Methods
Clear()
Removes all tracked objects and reference ID assignments, resetting the tracker
to its initial empty state with the next assignable ID starting at 1.
Declaration
public void Clear()
Remarks
Use this method when reusing a ReferenceTracker instance across multiple independent serialization or deserialization operations. After calling Clear(), the tracker behaves identically to a freshly constructed instance with the same Handling value.
IsTracked(object)
Determines whether the given object is currently registered in this tracker.
Declaration
public bool IsTracked(object obj)
Parameters
| Type | Name | Description |
|---|---|---|
| object | obj | The object to check using reference identity. If |
Returns
| Type | Description |
|---|---|
| bool |
|
See Also
Register(int, object)
Explicitly registers a deserialized object under a specific reference ID so that subsequent back-references in the same deserialization session can be resolved via TryResolve(int, out object).
Declaration
public void Register(int referenceID, object obj)
Parameters
| Type | Name | Description |
|---|---|---|
| int | referenceID | The reference ID read from the serialized data (e.g., from a |
| object | obj | The newly constructed object to associate with |
Remarks
If referenceID already exists in the reverse index, the
existing entry is overwritten. This can occur when a deserialized object's
reference is updated after initial construction (e.g., after property population).
See Also
TryGetID(object, out int)
Looks up the reference ID that was previously assigned to the given object without registering it or modifying the tracker state.
Declaration
public bool TryGetID(object obj, out int referenceID)
Parameters
| Type | Name | Description |
|---|---|---|
| object | obj | The object to look up. If |
| int | referenceID | On return, the reference ID assigned to |
Returns
| Type | Description |
|---|---|
| bool |
|
See Also
TryResolve(int, out object)
Resolves a reference ID to the object it was assigned to, enabling deserialization code to patch in back-references after their target objects have been constructed.
Declaration
public bool TryResolve(int referenceID, out object obj)
Parameters
| Type | Name | Description |
|---|---|---|
| int | referenceID | The integer ID to resolve. IDs are assigned starting from |
| object | obj | On return, the object associated with |
Returns
| Type | Description |
|---|---|
| bool |
|
See Also
TryTrack(object, out int)
Attempts to register an object with the tracker. If the object is being seen for
the first time, assigns it a new unique reference ID and returns false.
If the object was already registered, returns true (a cycle has been
detected) along with its previously assigned ID.
Declaration
public bool TryTrack(object obj, out int referenceID)
Parameters
| Type | Name | Description |
|---|---|---|
| object | obj | The object to track. If |
| int | referenceID | On return, the reference ID associated with |
Returns
| Type | Description |
|---|---|
| bool |
|