I have the following discriminated union type:
type Value =
| Float of float
| Int of int
| String of string
| Function of (ContextStack -> Value -> Value)
| Action of (unit -> Value)
| Constructor of string * int * Value
| Type of string * Context
| Object of Value * List<Value>
| Ref of Context * (Context -> Value) * (Context -> Value -> Context)
| Unrecognizable of Node
| Closure of Value * ContextStack * bool
| Application of Value * Value
where some constructors contain a field of type Context, which is basically just a System.Collections.Generic.Dictionary<string, Value> (and ContextStack is Context list). Because of that, there can be a situation, when a Value instance contains a reference to a dictionary, that contains said instance. Trying to print it using sprintf "%A", that recursively traverses the object, will result in unending recursion and StackOverflow error. But it is not really a problem for the application itself - as I never print these values anyway. However, when I am trying to debug my program, debugger tries to evaluate all object's string representation and fails with stack overflow.
To solve it, I tried to override ToString method, thinking the debugger uses it for string representation, but it didn't work. Even this:
type Value =
| Float of float
| Int of int
| String of string
| Function of (ContextStack -> Value -> Value)
| Action of (unit -> Value)
| Constructor of string * int * Value
| Type of string * Context
| Object of Value * List<Value>
| Ref of Context * (Context -> Value) * (Context -> Value -> Context)
| Unrecognizable of Node
| Closure of Value * ContextStack * bool
| Application of Value * Value
with override this.ToString(): string = "Please, don't crash!"
causes an error. What do I do?
Just in case:
- Operating System - Windows 11
- IDE - Rider 2024.3
- .NET project's target framework - netcoreapp 3.1 (I know it is not supported anymore - I heavily rely on an old library - changing it is not an option)
Update: it seems that debugger actually uses toString for string representation, but only if the object to represent is Value. Trying to sprintf "%A" dictionary, that contains Value object, will call sprintf "%A" on the contained Value object instead of its toString.