Some time ago, I had the the need to find out how a particular variable ended up having the value it had. The application involved was far too large to consider stepping through it, and there were just far too many other values that were added and subtracted for me to consider setting breakpoints on them all. Besides, ultimately, what I wanted to do was track down one particular value that was being added in and find out where it came from.
What I needed was a way to see what variables and values had been used to calculate the target variable’s values and be able to drill down into those variables to find the ultimate source of the number I was after. But that was something that didn’t exist. Variables don’t remember how they arrived at holding a particular value, just what value they currently hold.
I set out to change that and ended up creating the
tdecimal class. In my particular case, the variable type used throughout the system to represent monetary values was
t stands for
tracable and was chosen because it makes it easy change a variable type by simply adding a single letter to the declaration.
Below, I will present some images showing
tdecimal in use, so that, hopefully, the usefulness of this class can be seen. To keep the size of the posts to a reasonable size, I will post the code for
tdecimal in a subsequent post. After that I will post some explanations of how it can be used and why it is set up the way it is.
Before I begin, I just want to say that I know that a lot of what is currently in the
tdecimal class will be much easier to accomplish in .NET 4.5. I wanted to post the code in its current form so that I would have a record of the logic I used in developing it.
The following image shows a
tdecimal value in use and how various information from it can be viewed:
In this case, we are looking at the variable
SubTotal. The locals window shows that the current value of the variable is
310.344224. It is also possible to see that the last operation that occurred was that we added (
_operand) two source values (
0 comes from a value named “TPO_Summary: Total SQS Special” (which represents the variable
TotalSQSSpecial that appears as the last value in the add at line 422). The
341.344224 came from an unnamed value (in fact, this is the result of the 8 additions and subtractions that precede the addition of the
Note that the
310.344224 is itself a
tdecimal, which means that we can drill down into its
_sourceValues and find out what values were used to create it. If we did, we would see the addition of another
TotalSQSSpecial is a
tdecimal as well, but note that it has no
_sourceValues (indicating that it was never initialized – sloppy, very sloppy).
_name is a text value that can be assigned to
tdecimal. It could be the literal name of the variable, or, as seen above, it can be a more descriptive identifier for the value (which can prove useful when many classes and/or methods use the same identifiers for their variables).
Finally, you can see that the
310.344224 was assigned to
SubTotal at line 422 of the in the CalculateTotalOwing method in the source code file TastingPartyOrder.cs (
The next image shows a portion of a web page generated by the application. The programmers have the ability to display a table showing the breakdown of any
tdecimal value they wish. In this case, a partial drill-down into the value label “TPO_Summary: Total Owing” is shown:
In this image it is possible to see that the “Total Owing” was created by adding 3 values together ($329.58+$23.35+$0.00). One of the values (TPO_Summary: SubTotal) is further broken down to show that it is derived from the addition of 3 values ($262.48+$67.10+$0.00). And so on.
By clicking on the small + and – icons, any
tdecimal value can be expanded to see how it was derived.
Additionally, not shown above, is when the mouse is placed over any of the lines, the
_assignedAt text is shown in a tooltip, so it is possible to see in what file and at what line a value was assigned.
This tool has proved indispensable to to me in tracking down bugs or explaining system generated values. Our application is a business app, so it rarely does anything more complicated than dividing 2 numbers, but it is a relatively large application. Tracking down why a particular value is $67.19 and not $67.18 can be an arduous task without a tool like
In the next post I will present the code for
tdecimal and for the table display shown above. I know you may have some questions as to why
tdecimal shows its values the way it does. I hope to make all that clear in a subsequent post.