我开发并维护了一个用 C# 2.0 编写的大型 (500k+ LOC) WinForms 应用程序。它是多用户的,目前部署在大约 15 台机器上。该系统的开发正在进行中(可以被认为是永久测试版),并且几乎没有采取任何措施来保护用户免受每周构建中可能引入的潜在新错误的影响。
出于这个原因,除其他外,我发现自己变得非常依赖调试器中的编辑并继续。它不仅有助于寻找错误和修复错误,而且在某些情况下也有助于正在进行的开发。我发现能够从正在运行的应用程序的上下文中执行新编写的代码非常有价值——无需重新编译并向新代码添加特定的入口点(必须添加虚拟菜单选项、按钮等)应用程序并记住在下一次生产构建之前删除它们) - 一切都可以在不停止过程的情况下实时尝试和测试。
我非常重视编辑并继续,以至于我积极编写代码以完全兼容它。例如,我避免:
- 匿名方法和内联委托(除非完全不可能重写)
- 通用方法(稳定、不变的实用程序代码除外)
- 针对“任何 CPU”的项目(即从不以 64 位执行)
- 在声明点初始化字段(初始化移动到构造函数)
- 编写使用的枚举器块
yield
(实用程序代码除外)
现在,我完全意识到 C# 3 和 4 中的新语言特性在很大程度上与编辑并继续(lambda 表达式、LINQ 等)不兼容。这是我拒绝将项目升级到更新版本的框架的原因之一。
我的问题是避免使用这些更高级的结构来支持非常非常容易调试的代码是否是一种好习惯?这种发展有合法性,还是浪费?此外,重要的是,这些构造(lambda 表达式、匿名方法等)是否会产生性能/内存开销,而编写良好、编辑和继续兼容的代码可以避免这些开销?...或者 C# 编译器的内部工作是否使这种高级构造比手动编写的“扩展”代码运行得更快?