C# 如何找到赋值给哪个变量?

C# 如何找到赋值给哪个变量?,c#,.net,visual-studio,debugging,variables,C#,.net,Visual Studio,Debugging,Variables,我正在调试一个旧的C#应用程序。在一个屏幕上,我可以单击以对服务器运行查询并获得结果列表 问题是我很难弄清楚结果是如何计算的。每个结果都有一个与之关联的浮点数,并显示在屏幕上。为了便于讨论,假设第一个结果旁边的数字是123.45 我猜数字123.45必须在某个点上分配给一个浮点变量,但是如果有数百万行代码,我有很多挖掘工作要做 因此,我想知道,如果我确定123.45这个数字在某个点被分配给一个变量,有没有什么方便的方法可以找到它发生的地方以及分配给哪个变量?有没有调试工具可以做到这一点 编辑:这

我正在调试一个旧的C#应用程序。在一个屏幕上,我可以单击以对服务器运行查询并获得结果列表

问题是我很难弄清楚结果是如何计算的。每个结果都有一个与之关联的浮点数,并显示在屏幕上。为了便于讨论,假设第一个结果旁边的数字是123.45

我猜数字123.45必须在某个点上分配给一个浮点变量,但是如果有数百万行代码,我有很多挖掘工作要做

因此,我想知道,如果我确定123.45这个数字在某个点被分配给一个变量,有没有什么方便的方法可以找到它发生的地方以及分配给哪个变量?有没有调试工具可以做到这一点

编辑:这里的评论者正确地指出,我不确定这个数字是否分配给了一个变量;我只是猜测可能是这样。另外,我熟悉设置断点的条件,但这在这里没有帮助,因为要设置断点,您必须知道赋值发生在哪一行

我这里的问题是,是否有一种方法可以检测代码中未知位置的特定值被分配给未知变量。我想找到赋值发生的位置,以及赋值给哪个变量

第二次编辑:让我们将其与使用SQL探查器进行比较。如果我知道值123.45被插入到表中或作为参数传递到存储过程中,我可以使用SQL事件探查器并过滤包含字符串“123.45”的命令文本。这可能会找到用于将123.45发送到SQL server的确切命令。如果我正在寻找要分配给C#变量的值,但我不知道是哪一个,那么我可以做类似的事情吗


我认为答案可能是“不”,但我认为这里的某个人可能会对此有所了解。

如果您可以将范围缩小到更新屏幕的不同UI dispatchers,您可以添加一个条件来检查该特定值,如下图所示:


如果你的手表是vs 2012的话,你可以试着给它加一块手表吗?我不确定在您的环境中是否可以,但请在要查找它的方法调用的开始处设置一个断点。在变量上单击鼠标右键,然后单击“添加观察”并在底部跟随它。

考虑到这两种方法是不同的概念,添加另一个答案

找到它的一个可能的解决方案是添加一个小方法,该方法执行检查,并使用
Debugger.Break()
以编程方式中断调试会话

我担心我的WPF不是很好,所以我通过一个小的
事件处理程序直接向
控件.Items
添加值来快速模拟一个数据源,该处理程序在每次添加一个项时都会被调用(所以我模拟一个
OnItemSourceChanged
事件)

当然,您应该使用内置的数据绑定集合,但概念是相同的(如果您有一个使用“干净”方法的工作示例,请随意编辑和添加它)

考虑这个例子:

public partial class MainWindow : Window
{
    public event EventHandler<EventArgs> UpdateUI; 

    public MainWindow()
    {
        InitializeComponent();
        UpdateUI += sniff;

        PrintFromA();
        PrintFromB();
    }

    private void sniff(object sender, EventArgs e)
    {
        if (lstSample.Items.Contains(45))
        {
            Debugger.Break();
        }
    }

    private void updateUI(int i)
    {
        Dispatcher.Invoke(() =>
        {
            lstSample.Items.Add(i);
        });

        UpdateUI.Invoke(this, new EventArgs());
    }


    private void PrintFromA()
    {
        for (int i = 0; i < 50; i += 2)
        {
            updateUI(i);
        }
    }

    private void PrintFromB()
    {
        for (int i = 0; i < 50; i++)
        {
            updateUI(i);
        }
    } 
}
公共部分类主窗口:窗口
{
公共事件事件处理程序更新;
公共主窗口()
{
初始化组件();
UpdateUI+=嗅探;
PrintFromA();
PrintFromB();
}
私有无效嗅探(对象发送方、事件参数)
{
if(样本项包含(45))
{
Debugger.Break();
}
}
私有void updateUI(inti)
{
Dispatcher.Invoke(()=>
{
1.样品.项目.添加(i);
});
Invoke(这是新的EventArgs());
}
私有void PrintFromA()
{
对于(int i=0;i<50;i+=2)
{
更新(i);
}
}
私有void PrintFromB()
{
对于(int i=0;i<50;i++)
{
更新(i);
}
} 
}
我们仍在检查值是否为45,因此
PrintFromB
应该是我们正在寻找的方法(
PrintFromA
将绕过它)

当我们执行此操作时,我们可以看到当
PrintFromB
几乎完全执行时,我们的代码被暂停,就在刚刚添加45的位置

查看stacktrace,我们可以看到:


现在我们可以清楚地看到,这个值是通过
PrintFromB
方法得到的。转到stacktrace中的这一点将非常清楚地向您显示哪个变量保存您要查找的值。

不必指定给“变量”。例如,可能是UI元素的一部分。我假设您熟悉可以在断点上设置的条件?您有源代码吗?如果是这样的话,您可以设置断点并使用调用堆栈吗?在本机代码调试器中,您似乎能够在CPU寄存器的状态下中断。您可能要参加一个很长的调试会话,但您可以先在一个小测试程序上进行一次尝试,看看这是否可行:这是windbg和sos的实际操作。那个系列还有更多值得一看的视频。谢谢你的回答,但我不知道我能不能用这样的方式缩小范围。问题是应用程序的编写要比它需要的复杂得多。如果我知道要监视哪个变量,监视列表变量可能会有所帮助,但在这种情况下,我甚至不知道变量的名称!