VS2008调试器中类成员的C#get行为
我向我的一个朋友解释了一些模块,我不得不进入调试模式,通过设置断点来显示一些变量/属性的值 对于正常情况,如果我在get/set侧设置断点,则会为正常程序流命中断点,并显示正确的结果。VS2008调试器中类成员的C#get行为,c#,visual-studio-2008,C#,Visual Studio 2008,我向我的一个朋友解释了一些模块,我不得不进入调试模式,通过设置断点来显示一些变量/属性的值 对于正常情况,如果我在get/set侧设置断点,则会为正常程序流命中断点,并显示正确的结果。 有趣的是,VS debugger也将使用相同的方法(即调用get方法)来了解属性值 作为调试器,它应该能够获取程序的状态,而不会实际干扰程序或产生任何副作用。 尝试下面的代码设置几个断点,并将鼠标悬停在控制台的属性计数上。write()。您会发现计数会发生变化,而不会被get中的断点击中 只需将鼠标悬停在属性上,
有趣的是,VS debugger也将使用相同的方法(即调用get方法)来了解属性值 作为调试器,它应该能够获取程序的状态,而不会实际干扰程序或产生任何副作用。 尝试下面的代码设置几个断点,并将鼠标悬停在
控制台的属性计数上。write()
。您会发现计数会发生变化,而不会被get
中的断点击中只需将鼠标悬停在属性上,它就可以从属性中获取值,这在某些奇怪的调试会话中可能会让人难以理解 我知道人们会说get不应该修改成员或糟糕的设计,但在某些情况下,最好用get()编写,比如测试null,如果为null,则返回一个新对象
public class Test
{
int _count;
public int Count
{
get
{
_count++;
return _count;
}
}
}
public class Program
{
static void Main(string[] args)
{
Test tCount = new Test();
Console.Write(tCount.Count);
}
}
您认为这是VS的正确行为吗?
因为调试器不应该修改程序的状态。
即使它修改了状态,也应该通过断点
我能想到的唯一原因是,调试器没有单步通过断点,它必须停止/中断自身的调试线程,以命中断点,从而停止它。属性getter或setter基本上与方法相同。调试器在评估时无法防止副作用。如果您不想产生副作用,那么可以使用调试器直接读取字段的值(在您的示例中为计数)。调试器只是类的另一个客户端,因此需要执行类的代码以向您提供值。在此过程中,调试器可能会更改类的状态。
然而,只要遵循设计准则,使getter尽可能简单,这就不应该是一个问题。如果更改getter中的值,则很可能违反了。在我看来,这是getter的理想行为方式。如果希望工具提示显示property值,则显然需要调用该属性。i、 首先,我不希望这会导致调试器崩溃。这正是我所希望的。当然,这是正确的行为。您要求它评估
Count
,它照做了。它是如何知道您真的希望它评估\u count
属性和字段并不总是一对一地配对。属性更像是方法而不是字段。您是否也希望能够执行没有副作用的方法
setter属性呢?如果您使用调试器故意更改属性的值,您真的希望该值保持不变吗?getter被悄悄地用[SpecialName]属性修饰。这在一定程度上改变了目标帖子,原因如下。将代码更改为
public class Test
{
int _count;
public int Count
{
get
{
_count++;
throw new Exception("hello");
return _count;
}
}
}
在执行之前,将鼠标悬停在console.writeline上。您将看到调试器报告发生了异常!否则,您将不会有这种类型的报告。是的,这是预期的行为。我明白你的意思,但这就像一条物理规则,你不能不影响它就观察任何东西。a,是的,因为调试器只是我的类的另一个客户端,如果你把它当作调用和使用我的类的人,但a不是,因为调试器不应该修改或更改程序的状态。即使现在,我在程序和设计上也没有问题。我关心的是为什么会有副作用。好的,正如你所说的,它是我的另一个客户端,那么它应该逐步完成get代码并点击断点。确切地说,它不希望导致调试器在breakpoit集本身中断。这将是自相矛盾的。