我开发和维护一个用 C# 2.0 编写的大型(500k+ LOC)WinForms 应用程序。它是多用户的,目前部署在大约 15 台机器上。系统的开发正在进行中(可以被认为是永久测试版),并且几乎没有采取任何措施来保护用户免受每周构建中可能引入的潜在新错误的影响。
出于这个原因,除其他外,我发现自己变得非常依赖调试器中的“编辑并继续”。它不仅有助于查找错误和修复错误,在某些情况下还有助于持续开发。我发现能够在正在运行的应用程序的上下文中执行新编写的代码非常有值(value) - 无需重新编译并向新代码添加特定的入口点(必须添加虚拟菜单选项、按钮等)应用程序并记住在下一次生产构建之前删除它们)- 一切都可以在不停止过程的情况下实时尝试和测试。
我非常重视编辑并继续,因此我积极编写代码以使其完全兼容。例如,我避免:
- 匿名方法和内联委托(delegate)(除非完全不可能重写)
- 通用方法(稳定、不变的实用程序代码除外)
- 针对“任何 CPU”上的项目(即从不在 64 位上执行)
- 在声明时初始化字段(初始化移至构造函数)
- 编写使用
yield
的枚举器 block (实用程序代码除外)
现在,我完全意识到 C# 3 和 4 中的新语言特性在很大程度上与“编辑并继续”(lambda 表达式、LINQ 等)不兼容。这是我拒绝将项目升级到更新版本的框架的原因之一。
我的问题是,避免使用这些更高级的结构来支持非常非常容易调试的代码是否是一种好的做法?这种发展是否合法,还是浪费?此外,重要的是,这些构造(lambda 表达式、匿名方法等)中的任何一个是否会产生性能/内存开销,而编写良好、编辑并继续兼容的代码可以避免这些开销? ...还是 C# 编译器的内部工作原理使此类高级构造比手动编写的“扩展”代码运行得更快?
最佳答案
不想听起来陈腐 - 编写单元/集成测试而不是依赖编辑继续是一种很好的做法。
这样,您付出一次努力,其他时间都是“免费”的...
现在我不是建议您回顾性地为所有代码编写单元;相反,每次你必须修复一个错误时,首先要编写一个测试(或更常见的多个测试)来证明修复。
正如@Dave Swersky 在评论中提到的,Mchael Feathers 的书,Working Effectively with Legacy Code是一个很好的资源(它是你写完后 5 分钟的遗产,对吧?)
所以是的,我认为避免使用新的 C# 结构以支持编辑和继续是错误的;但我也认为仅仅为了它而采用新结构是错误的,尤其是当它们导致代码更难理解时。
关于c# - 避免或接受中断编辑并继续的 C# 构造?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3865454/