views:

242

answers:

5

How can I track a variable's values as they change, at runtime, in C#? I'm interested in the same functionality that the debugger provides when I'm tracing a variable through execution steps, only that I need to call upon it from my code. Some sort of key-value observing, but for all kinds of variables(local, class, static, etc), not only properties. So, basically, receive a notification when a variable's value changes.

A: 

The only sensible way you could do that without the debugger would be: don't use a variable, but use a property, and (perhaps conditionally) add trace to the setter:

private int myValue;
public int MyValue {
    get {return myValue;}
    set {
        SomeTraceMethod(myValue, value, ...);
        myValue = value;
    }
}

Obviously this cannot then be used for arbitrary fields/variables.

Marc Gravell
How does the debugger do it for arbitrary variables? Isn't there a debugging library that could help me achieve the same level of tracking?
luvieere
+3  A: 

To add to what Marc said, if you want to do this for lots of properties and methods you might want to check out aspect oriented programming techniques, and libraries such as PostSharp.

http://www.sharpcrafters.com/postsharp

jkohlhepp
A: 

As others mentioned a mechanism like that makes only sense when using properties. In .NET you can then make use of the INotifyPropertyChanged interface.

For a sample how to implement it see

How to: Implement the INotifyPropertyChanged Interface

The referenced article talks explicitly about Windows Forms, but you are not bound to that (the interface is actually declared in the System.ComponentModel namespace in System.dll). In fact, this interface is widely used for data binding scenarios, e.g. in WPF.

0xA3
I mentioned in the question that I'm interested in arbitrary variables, not properties. I know about INotifyPropertyChanged, what I don't know is how to trace arbitrary variables, like the debugger does.
luvieere
+1  A: 

You are working from the assumption that the debugger can track variable changes. It can't.

It is possible with unmanaged code, the processor has dedicated debug registers that allow setting data breakpoints. Up to three are provided. It generates a hardware interrupt when it sees a particular memory location getting written. This otherwise very useful feature isn't available in managed code however. The garbage collector is completely incompatible with it, it moves objects around, giving them another address.

The managed debugger does support a "when hit" condition on a breakpoint, allowing you to dump info to the output window. That however requires a breakpoint, it cannot be triggered by a change in variable value. It also really slows down code execution since the debugger actually enters a break state before executing the condition.

The obvious place to put such a breakpoint is in a property setter. Which is what you'll need to implement this feature in code. You can do anything you want in that setter, using the Trace class for example.

Hans Passant
A: 

The managed debugger uses the ICorDebug COM API for pretty much everything. The part that you're interested is ICorDebugValue and its descendants. Note that a LOT of the debugging API requires that the process be not running (ie, have encountered a breakpoint) in order for the various inspections to happen. A high level overview of ICorDebug is here. The documentation on it is kinda sparse, but some Googling may help. Good luck.

Donnie