我正在向我的一位朋友解释一些模块,我不得不进入调试模式,通过设置断点来显示一些变量/属性的值。
正常情况下,如果我将断点设置在get / set的一侧,则断点将被正常程序流程点击并显示正确的结果。
我发现有趣的是VS调试器也会使用相同的(即调用get方法)来知道属性值。
作为调试器,它应该能够获得程序的状态而不会实际干扰它或产生任何副作用。
尝试以下代码设置几个断点并将鼠标悬停在console.write()
的属性计数上。你会发现计数的变化没有被get
内的断点所击中
只需将鼠标悬停在属性上,它就可以从中获取值,这在一些奇怪的调试会话中可能很难理解。
我知道人们可以说get不应该修改成员或糟糕的设计,但在某些情况下最好写入get(),例如测试null并返回一个新对象,如果它为null; < / p>
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的正确行为吗?,
由于调试器不应该修改程序的状态。 即使它修改了状态,它也应该逐步通过断点。
只有我能想到为什么调试器没有单步执行断点的原因是它必须停止/中断自身的调试线程以触发断点,这将阻止它。
答案 0 :(得分:3)
属性getter或setter与方法基本相同。调试器在评估时无法阻止副作用。如果您不想要副作用,请使用调试器直接读取字段的值(示例中为_count)。
答案 1 :(得分:1)
调试器只是您类的另一个客户端,因此需要执行类的代码以向您显示值。在执行此操作时,调试器可能会更改您的类的状态 但是,只要您遵守设计准则以使吸气剂尽可能简单,这确实不应成为问题。如果您更改了getter中的值,则很可能违反了SRP。
答案 2 :(得分:1)
答案 3 :(得分:1)
当然这是正确的行为。你要求它评估Count
所以它确实如此。如何知道您真的希望它评估_count
?
属性和字段并不总是一对一配对。属性更像是方法而不是像字段。您是否希望能够执行没有副作用的方法?
如何设置属性?如果您使用调试器故意更改属性的值,那么真的希望值保持不变吗?
答案 4 :(得分:0)
使用[SpecialName]属性安静地装饰吸气剂。这有点改变了目标职位,这是一个原因。将您的代码更改为...
public class Test
{
int _count;
public int Count
{
get
{
_count++;
throw new Exception("hello");
return _count;
}
}
}
并在执行之前将鼠标悬停在console.writeline上。您将看到调试器报告发生了异常!否则你不会有这种类型的报告。是的,这是预期的行为。