Table of Contents

Class State

Namespace
Microsoft.Accordant
Assembly
Accordant.dll

State class represents the state maintained by the user of a system to make sense of the behavior of the system. It is not the internal state of the system though it is probably similar to the internal state of the system.

This is an abstract class and defines properties and methods that should be implemented by all state objects.

public abstract class State : IState
Inheritance
State
Implements
Inherited Members

Fields

stateHash

protected ulong? stateHash

Field Value

ulong?

stringRepresentation

protected string stringRepresentation

Field Value

string

Properties

EnableFreezeValidation

Controls whether ValidateNotMutated() performs validation. Set to false to disable validation for performance in production scenarios. Default is true.

public static bool EnableFreezeValidation { get; set; }

Property Value

bool

IsFrozen

Indicates whether a state object is frozen (immutable). State objects are not frozen when initially created so the user can modify the state in an 'imperative' fashion. They are then frozen by the framework once returned from the method that created them so they are effectively immutable. Once frozen, the only way to modify a state object is to clone it to create a new state object that can be modified till it's also eventually frozen.

[JsonIgnore]
public bool IsFrozen { get; protected set; }

Property Value

bool

Random

public static Random Random { get; }

Property Value

Random

Methods

AppendFieldHashes(XxHash64, Dictionary<object, int>)

Appends hash data for this state's fields to the hasher. Override in derived classes for efficient incremental hashing. The cycle check is handled by AppendHashCore(XxHash64, Dictionary<object, int>) - this method only needs to append field data.

protected virtual void AppendFieldHashes(XxHash64 hasher, Dictionary<object, int> visited)

Parameters

hasher XxHash64

The XxHash64 hasher to append data to.

visited Dictionary<object, int>

Dictionary of already-visited objects, passed to nested states.

AppendHashCore(XxHash64, Dictionary<object, int>)

Appends this state's hash data to the provided hasher. This method handles cycle detection and delegates to the generated override. Nested states call this method to append directly to the parent's hasher, avoiding early collapse to 64 bits.

public void AppendHashCore(XxHash64 hasher, Dictionary<object, int> visited)

Parameters

hasher XxHash64

The XxHash64 hasher to append data to.

visited Dictionary<object, int>

Dictionary mapping visited objects to their reference IDs for back-reference handling.

AppendLengthPrefixedString(XxHash64, string)

Appends a length-prefixed string to the hasher. The length (in bytes) is prepended to prevent boundary collisions (e.g., "ab" + "c" vs "a" + "bc").

public static void AppendLengthPrefixedString(XxHash64 hasher, string value)

Parameters

hasher XxHash64

The XxHash64 hasher to append data to.

value string

The string to append.

Clone()

Clones the state object. The cloned state object is initially not frozen.

public virtual State Clone()

Returns

State

Clone(Dictionary<object, object>)

Clones the state object. This method is supposed to be called by other State objects internally and should not be directly called by users.

public State Clone(Dictionary<object, object> clonedMap)

Parameters

clonedMap Dictionary<object, object>

Returns

State

CloneInternal(Dictionary<object, object>)

This method should clone the state set the cloned state in the map. It does not need to check whether the clone is already present in clonedMap or not as it is only called if there is not an entry in clonedMap. It should however set the clone in the map, before calling the Clone method on its sub-components (as they may recursively point back to the parent).

protected abstract void CloneInternal(Dictionary<object, object> clonedMap)

Parameters

clonedMap Dictionary<object, object>

CloneWithMap()

Clones the state object. The cloned state object is initially not frozen. This also returns a map that maps objects in the original state to corresponding objects in the cloned state.

public (State, Dictionary<object, object>) CloneWithMap()

Returns

(State, Dictionary<object, object>)

CloneWithMap<TState>()

public (TState, Dictionary<object, object>) CloneWithMap<TState>() where TState : State

Returns

(TState, Dictionary<object, object>)

Type Parameters

TState

ComputeHash64(string)

Computes a 64-bit hash of the given string using XxHash64.

public static ulong ComputeHash64(string str)

Parameters

str string

Returns

ulong

Freeze()

Freezes the state, making it immutable. Any attempts to modify a frozen state object should result in the StateFrozenException exception being thrown.

public void Freeze()

Freeze(HashSet<object>)

public void Freeze(HashSet<object> visited)

Parameters

visited HashSet<object>

FreezeComponents(HashSet<object>)

Derived state objects must recursively call FreezeComponents(HashSet<object>) on state objects they are composed of.

protected abstract void FreezeComponents(HashSet<object> visited)

Parameters

visited HashSet<object>

GetStableTypeName(Type)

Gets a stable type name that doesn't include assembly-qualified generic type arguments. For non-generic types, returns the same as Type.FullName. For closed generics (e.g., Container<ItemState>), Type.FullName includes assembly version info in the generic arguments, making fingerprints/hashes version-dependent. This method strips that info, producing a name like: "Ns.Container1[Ns.ItemState]" instead of "Ns.Container1[[Ns.ItemState, Assembly, Version=...]]"

public static string GetStableTypeName(Type type)

Parameters

type Type

Returns

string

GetStateHash()

Returns the 64-bit state hash, computed incrementally using XxHash64. Cached for frozen states.

public ulong GetStateHash()

Returns

ulong

LockComponents(HashSet<object>)

Obsolete. Override FreezeComponents(HashSet<object>) instead.

[Obsolete("Override FreezeComponents instead")]
protected virtual void LockComponents(HashSet<object> visited)

Parameters

visited HashSet<object>

StringRepresentation()

Returns a string representation of the state. The string representation of the state is not just a human-friendly text representation but also serves as the value over which the state hash is computed. Care must be taken to ensure that two different state objects must have different string representations; they will map to the same state hash if they are not different.

public string StringRepresentation()

Returns

string

StringRepresentation(bool)

Returns the string representation, optionally bypassing the cache.

public string StringRepresentation(bool forceRecompute)

Parameters

forceRecompute bool

If true, recomputes even for frozen objects (propagates to nested states).

Returns

string

StringRepresentation(Dictionary<object, string>, string)

See StringRepresentation() for details. This method should not be directly called by users and only by other classes that inherit from the State class.

public string StringRepresentation(Dictionary<object, string> objectPaths, string path)

Parameters

objectPaths Dictionary<object, string>
path string

Returns

string

StringRepresentation(Dictionary<object, string>, string, bool)

Internal overload with forceRecompute parameter.

public string StringRepresentation(Dictionary<object, string> objectPaths, string path, bool forceRecompute)

Parameters

objectPaths Dictionary<object, string>
path string
forceRecompute bool

Returns

string

StringRepresentationInternal(Dictionary<object, string>, string, bool)

Derived classes must implement this method to return a unique string representation of the state they represent. The derived class should call the StringRepresentation(Dictionary<object, string>, string, bool) method when fetching the string representation of sub-components. They must pass the objectPaths, path, and forceRecompute parameters to the nested calls.

protected abstract string StringRepresentationInternal(Dictionary<object, string> objectPaths, string path, bool forceRecompute)

Parameters

objectPaths Dictionary<object, string>
path string
forceRecompute bool

Returns

string

ToString()

public override string ToString()

Returns

string

ValidateNotMutated()

Validates that a frozen state has not been mutated since it was frozen. Throws StateFrozenException if mutation is detected. This check can be disabled by setting EnableFreezeValidation to false.

public void ValidateNotMutated()

Exceptions

StateFrozenException

Thrown if the state was mutated after freezing.