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.
问题:
回答1:
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.
回答2:
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
回答3:
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.
回答4:
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.
回答5:
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.