我正在处理的项目在主 C# 文件中刚刚达到 4200 行,这导致 IntelliSense 需要几秒钟(有时长达 6 秒左右)才能响应,在此期间 Visual Studio 会锁定。我想知道其他人如何分割他们的文件以及是否达成共识。

我尝试寻找一些指南并发现 Google 的 C++ 指南, ,但我看不到任何有关语义的信息,例如函数大小和文件大小;也许它就在那里——我已经有一段时间没看过它了。

那么如何分割文件呢?您是否按照方法所服务的功能对方法进行分组?按类型(事件处理程序、私有/公共)?拆分函数的大小限制是多少?

需要澄清的是,所讨论的应用程序处理数据 - 因此它的界面是一个大网格,并且一切都围绕网格旋转。它有一些用于管理的对话框形式,但都是关于数据的。它如此之大的原因是有大量的错误检查、事件处理以及设置为主从的网格,每行还有三个网格(但这些负载在主行上扩展)。我希望这有助于澄清我的观点。

有帮助吗?

解决方案

我认为您的问题总结为您使用的术语:“主C#文件”。

除非你的意思是main(如方法main()),否则就没有这个概念的地方。

如果你有一个catch-all实用程序类或其他常用方法,你应该将它们分解为类似的功能部分。

通常我的文件只是一对一的类映射。

有时,非常相关的类在同一个文件中。

如果您的文件太大,则表明您的课程太大而且过于笼统。

我尝试将我的方法保持在半个屏幕或更少。 (当我从头开始编写代码时,它通常是12行或更少,但最近我一直在使用其他开发人员的现有代码,并且不得不重构100行函数......)

有时它是一个屏幕,但是它变得非常大。

编辑:

要解决关于函数的大小限制问题 - 对我而言,它不是关于大小(尽管这是一个很好的问题指示器),而是关于只做一件事并保持每一个简单。

其他提示

经典书中《结构化编程“ Dijkstra 曾经写过一段标题为:“关于我们无法做很多事情。”他的观点很简单。人类并不是很聪明。我们无法同时在脑海中处理多个概念。

保持类和方法较小非常重要。当一个方法超过十几行左右时,就应该将其分解。当一个类超过几百行时,就应该将其分解。这是保持代码良好组织和可管理的唯一方法。我从事编程工作已经近 40 年了,随着时间的流逝,我越来越意识到“小”这个词在编写软件时有多么重要。

至于 如何 你这样做,这是一个非常大的话题,已经被写过很多次了。一般来说,这都是关于依赖管理、信息隐藏和面向对象设计的。这是一个阅读清单。

将你的类型拆分成自然分割的类型 - 但要注意那些做得太多的类型。在大约500行(Java或C#)我很担心。在大约1000行,我开始认真考虑是否应该拆分类型......但有时它不能/不应该。

至于方法:当我无法一次在屏幕上看到整个方法时,我不喜欢它。显然这取决于显示器的大小等,但这是一个合理的经验法则。我更喜欢它们更短。同样,也有例外 - 某些逻辑很难解开,特别是如果有很多局部变量本身并不希望被封装在一起。

有时单个类型有一个 lot 方法是有意义的 - 例如 System.Linq.Enumerable 但是在这种情况下,如果您可以将类型分解为逻辑组(在 Enumerable 的情况,通过聚合/设置操作/过滤等进行分组似乎很自然)。根据我的经验,这种情况很少见。

Martin Fowler的书重构我认为这为你提供了一个很好的起点。它指示如何识别“代码味道”。以及如何重构代码以修复这些“气味”。自然结果(虽然它不是主要目标)是你最终得到更小的可维护类。

修改

根据您的编辑,我一直坚持认为后端代码的良好编码实践在表示层中是相同的。 UI重构要考虑的一些非常有用的模式是命令,策略,规范和状态。

简而言之,您的视图应该只包含代码来处理事件和分配值。所有逻辑都应该分成另一个类。一旦你这样做,你会发现在你可以重构的地方变得更加明显。网格使得 little 更加困难,因为它们使得在表示逻辑和视图之间拆分表示状态变得太容易了,但是通过一些工作,你可以放置间接以最小化由此引起的痛苦

不要在程序上进行编码,并且在一个文件中最终不会有4,200行。

在C#中,最好遵守一些 SOLID 面向对象的设计原则。每个班级都应该只有一个改变的理由。主要方法应该只是启动应用程序的起始点(并配置您的依赖注入容器,如果您使用的是StructureMap)。

我通常没有超过200行代码的文件,如果他们不到100,我更喜欢它们。

没有严格的规则,但人们普遍认为更多,更短的功能比单个大功能更好,更小的类比1大类更好。

大于40行左右的功能应该让你考虑如何分解它。特别是看看嵌套循环,这些循环很容易混淆,并且通常很容易转换为具有良好描述性名称的函数调用。

当我觉得他们做的不仅仅是一件事,比如混合演示和逻辑时,我就分手了。只要班级做了一件事,一个大班级就不是一个大问题而是一个大问题。

我见过的样式指南中的共识是通过访问对方法进行分组,顶部是构造函数和公共方法。任何一致都很棒。

您应该阅读C#样式和重构,以真正了解您正在解决的问题。

重构是一本优秀的书,其中包含重写代码的提示,以便保留行为但代码更清晰,更易于使用。

C#Style的元素是一个很好的死树C#风格指南,这个博客文章有许多指向良好在线风格指南的链接。

最后,请考虑使用 FxCop StyleCop 。这些对您提出的问题没有帮助,但可以检测代码的其他风格问题。因为你已经将脚趾浸入水中,所以你也可以跳进去。

这很多,但是开发品味,风格和清晰度是优秀开发者和不良开发者之间的主要区别。

每个班级都应该做一件小事,做得好。你的班级是一个表格吗?然后它不应该有任何业务逻辑。

它是代表一个单一的概念,如用户还是国家?然后它不应该有任何绘图,加载/保存等...

每个程序员都要经历各个阶段和关卡。您认识到当前级别的问题,并且您已准备好接近下一级。

根据你的说法,听起来你现在的水平是“解决问题”,最有可能是使用程序代码,你需要开始更多地寻找新方法来接近它。

我建议如何真正做OO设计。有许多理论你可能听说过没有意义。他们不这样做的原因是他们不适用于你目前的编程方式。

Lemme找到一个好帖子......看看这些开头:

我如何打破我的程序编码-habits

有任何规则,适用于oop

面向对象 - 最佳实践 - 继承-v组成 - -v-接口

还有一些帖子会将您推荐给优秀的OO设计书籍。 A“重构”这本书可能是你可以开始的最好的地方之一。

你现在处于一个好点,但你不会相信你必须走多远。我希望你对此感到兴奋,因为在不久的将来,这些东西中的一些是最好的编程“学习经历”。你将永远拥有。

祝你好运。

你可以寻找一些小事情来改变,并随着时间的推移慢慢改变。

  • 所有方法都只在该类中使用吗?寻找可以移出到 helper/util 类中的支持方法,例如验证、字符串操作。

  • 您是否使用#region 部分?#region 中相关方法的逻辑分组通常适合分为单独的类。

  • 类是一种形式吗?考虑将用户控件用于表单控件或表单控件组。

有时,由于许多开发人员在不考虑整体设计的情况下进行快速修复/新功能,大型类会随着时间的推移而演变。重新审视其他人在这里提供的一些设计理论链接,并考虑持续的支持来执行这些链接,例如代码审查和团队研讨会来审查设计。

好吧,我想说您手头可能有一个比加载时间慢更大的问题。您将遇到紧密耦合的代码和可维护性/可读性问题。

有很好的理由将类文件分割成更小的文件(同样有很好的理由将文件移动到不同的项目/程序集)。

想想你的班级应该达到的目的是什么。每个文件实际上应该只有一个用途。如果它的目标过于笼统,例如“包含购物篮逻辑”,那么您就走上了错误的道路。

另外,如上所述,您使用的术语:“C# 主文件”只是让人觉得你有一种非常程序化的心态。我的建议是停下来,退后一步,快速阅读以下一些主题:

  • 一般面向对象编程原则
  • 领域驱动设计
  • 单元测试
  • 国际奥委会 集装箱

祝您搜索顺利。

使用部分课程。您基本上可以将一个类分成多个文件。

也许OP可以回应:您的项目是否使用面向对象编程?您使用“文件”一词的事实表明它不是。

在您理解面向对象之前,没有希望以任何重要方式改进您的代码。你最好不要拆分文件,等到它变得无法忍受缓慢和错误,然后不再支持它,去学习OO。

Visual Studio 2008中的Intellisense解析器似乎比2005年快得多(我知道他们在这个领域特别做了很多工作),所以尽管你应该在某些时候将文件拆分为其他人已经提到,Visual Studio 2008可能会解决您的即时性能问题。我已经用它来打开100K +行Linq到SQL文件而没有太多问题。

拆分代码,使每个类/文件/函数/等。只做一件事#8482; 单一责任原则是将功能划分为类的良好指南。

如今,我写的最大的课程大约有200行,而且这些方法大多是1-10行。

如果一个类中有代码区域,一个简单的方法是使用 partial 关键字并将该类的定义分解到该文件中。我通常会为大班做这件事。

我使用的约定是拥有ClassName_RegionName.cs。例如,如果我想打破一个管理数据库连接模式的类,并且我调用了类DatabaseConnection,我将为主类创建一个名为DatabaseConnection.cs的文件,然后为模式功能创建一个DatabaseConnection_Schema.cs文件。 / p>

有些课程必须很大。这不错设计;他们只是执行力很大。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top