如何避免属性递归

Ian*_*Ian 48 c# recursion properties

这最近打击了我正在进行的一个项目.大多数人都熟悉属性递归:

public int Test 
{
   get { return this.test; }
   set { this.Test = value; }
}
private int test;
Run Code Online (Sandbox Code Playgroud)

你不小心把一个大写的T放在这个setter中,你已经把自己打开了StackoverflowException.更糟糕的是,如果你没有定义它,通常visual studio会自动纠正套管,使你进入无效状态.

我最近在构造函数中做了类似的事情:

public TestClass(int test)
{
    this.Test = Test;
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,你没有得到StackOverflowException,现在你遇到了编程错误.在我的情况下,这个值被传递给一个WebService,而后者使用了一个默认值(不是0),这导致我错过了我错误地分配它的事实.集成测试全部通过,因为该服务没有说

"嘿,你忘记了这个非常重要的领域!"

我可以采取哪些措施来避免这种行为?我一直被建议不要像以下那样定义变量,我个人不喜欢它们,但我想不出任何其他选择:

private int _test;
private int mTest;
Run Code Online (Sandbox Code Playgroud)

编辑

通常我可以想到的下划线或m前缀不合适的原因是:

  • 可读性
  • 如果您继续使用第三方课程,因为您可以混合使用样式,那么滚动成员会稍微困难一些.

Sri*_*vel 62

最好的方法是在这里使用"自动实现的属性".

public int Test { get; set; }
Run Code Online (Sandbox Code Playgroud)

如果由于某种原因不能使用"自动实现的属性"使用_前缀(我不喜欢).

如果您也不想使用某些前缀,那么您还有其他选择.您不必手动编写属性代码.让IDE为你做; 这样你可以避免粗心的错误.(我不知道我在原始答案中是如何错过的)

只需输入

private int test;
Run Code Online (Sandbox Code Playgroud)

选择字段,右键单击Refactor-> Encapsulate Field.IDE将为您生成属性片段,如下所示.

public int Test
{
    get { return test; }
    set { test = value; }
}
Run Code Online (Sandbox Code Playgroud)

您无需费心单击上下文菜单.如果您更喜欢键盘,则快捷键为Ctrl+ R+ E.

或者得到一个Resharper,它会立即指出你的愚蠢错误.

  • @Katana314当然,我已经提到过,在我的回答中也不是吗?*如果由于某种原因无法使用"自动实现的属性",请使用_前缀* (12认同)
  • 是的...所以我没有理由为什么有人会贬低你.一般来说,自动属性不是一种坏习惯. (4认同)
  • 我没有downvote,但我很确定可能有许多情况需要直接访问支持变量 - 或者,有人想在设置功能中执行一些小动作.也就是说,我喜欢在可以的时候利用这些. (2认同)

Dav*_*vid 33

集成测试全部通过

然后他们没有详尽的测试.如果测试没有发现错误,那么您还需要另外一个测试.

这真的是这里唯一的自动化解决方案.编译器不会抱怨,因为代码在结构和语法上都是正确的.它在运行时没有逻辑上的正确性.

您可以定义命名标准,甚至使用StyleCop等工具来尝试执行这些标准.这可能会让你覆盖很多,虽然它不是一个铁定的解决方案,错误仍然可以通过.就个人而言,我同意你的看法,装饰变量名称在代码中是不雅观的.也许在某些情况下,这是一个有效的权衡?

最终,自动化测试可以防御这些错误.最简单的是,如果错误通过您的测试并进入生产,那么响应应该是:

  1. 编写测试以重现错误.
  2. 修复错误.
  3. 使用该测试验证修复.

当然,这只涵盖了一个案例,而不是代码中的每个属性定义.但如果这种情况发生很多,那么您可能会遇到人员问题,而不是技术问题.团队中有人是邋.的.该问题的解决方案可能不是技术问题.


Sla*_*avo 6

使用代码段.

对于由私有字段支持的每个属性,请使用您创建的自定义代码段,而不是从头开始编写它或让IntelliSense完成工作(很差).

毕竟,这个问题是关于惯例和纪律,而不是语言设计.C#的区分大小写特性和Visual Studio中完美的代码完成是我们犯这些错误的原因,而不是我们缺乏知识和设计.

你最好的选择是消除事故发生的可能性,并且正确地编写这些重复的东西是最好的方法.与记住约定并手动执行约定相比,它也更加自动化.

Visual Studio中有一个默认的代码段.键入propfull并按Tab键,然后指定实例变量名称和属性名称,您就可以开始使用了.