Our code allows a user to set a parameter and its value.
A value may be a reference to another parameter.
Parameter.Set("Parameter1", "%Parameter2%");
Parameter.Set("Parameter2", "%Parameter1%");
The actual resolving of this value uses Regex class’s Replace method to resolve any references inside % symbols recursively, and replace them:
// Pseudo code (the actual parameter name is retrieved and replaced with its value.
Regex.Replace("%Parameter1%", match => Parameter.Get(match));
In this case, a cyclic reference will cause a StackOverflowException.
How can this be avoided? (In case a cyclic reference is detected – throw an exception/handle in some way)
A proposed implementation was to keep a list of terms that were already looked for in the current resolving execution (a “Search History”).
For each step, look if the current searched parameter is in the history, if it is — we’ve looked at it already, and we must be in a cycle.
The downside to this approach is that it’s wasteful (allocate a new List for each parameter resolving that occurs).
As I suggested above, rewrite the signature of the recursive method as
Parameter.Get(string, int). Use the int as a recursion depth counter. Each time the method needs to evaluate a deeper parameter, decrement the int variable. When it reaches 0, stop processing parameters. The initial value of int can be a pretty small number, since few people will use 20 recursive parameters.