C#的部分类是不好的设计?

dfe*_*aro 68 .net c# vb.net

我想知道为什么'部分类'概念甚至存在于C#/ VB.NET中.我正在开发一个应用程序,我们正在阅读一本(实际上是非常好的)书,它与我们正在实施的开发平台相关.在本书中,作者提供了围绕平台API的大型代码库/包装器,并解释了他在教授有关平台开发的不同主题时如何开发它.

无论如何,长话短说 - 他在整个地方使用部分类,作为在C#(IMO)中伪造多重继承的一种方式.为什么他不只是把课程分成多个,而且使用构图超出了我.他将拥有3个"部分类"文件来构成他的基类,每个文件有3-500行代码......并且在他的API中执行了几次.

你觉得这有道理吗?如果是我,我会跟踪SRP并创建多个类来处理不同的必需行为,然后创建一个基类,将这些类的实例作为成员(例如组合).为什么MS甚至将部分类放入框架中?他们删除了在C#中扩展/折叠每个范围级别的所有代码的能力(这在C++中是允许的),因为它显然只是允许坏习惯 - 部分类,IMO,同样的事情.我想我的问题是:你可以向我解释什么时候有合理的理由使用分段课程吗?

编辑:我知道对于Web/WinForms,别无选择.但除此之外?为什么MS没有把一些不同的关键字用于粘合代码 - genn'ed类?或者真的有一个合理的设计方案值得吗?

我不是说这是一个咆哮/战争线程.老实说,我想在这里学点东西.应该在代码设计中何时使用部分类?简单的问题,无需关闭

谢谢

Joh*_*lla 97

你可以向我解释什么时候有合理的理由使用偏僻的课程吗?

最合理和最有用的原因之一是鼓励将自动生成的代码与您自己的自定义扩展分离.例如,从某种设计器中获得自动生成的表单代码是很常见的,但是您通常希望为其添加自己的特定行为.这样,如果重新生成自动代码部分,则不会触及具有特定扩展名的部分.

也就是说,很可能有太多好事.一些技巧:

  • 不要partial为了存在而上课partial.

  • 除了彼此以外,不要将部分课程放在任何地方.如果你必须跳转到项目的一个完全不相关的部分来查看该类的另一半,你可能做错了.

  • 不要使用partial技术来模糊类的大小.如果你partial因为课程太大而分手,你应该重新审视单一责任原则.

  • 如果你有partial同一个班级的三个或更多片段,几乎可以保证你会滥用部分片段.二是合理性的典型上限,它通常用于从手写代码中分割自动生成的代码.

无论如何,长话短说 - 他在整个地方使用部分类,作为在C#(IMO)中伪造多重继承的一种方式.为什么他不把这些课分成多个,并且使用作文超出了我.他将拥有3个"部分类"文件来构成他的基类,每个文件有3-500行代码......并且在他的API中执行了几次.

是的,这绝对是一个明显的滥用partial!

  • @defarraro:没有从.NET中删除多重继承 - 它从未添加过. (11认同)
  • @dferraro»代码是代码是代码.编译器无法区分生成的代码和人类输入的代码之间的区别,没有一些特殊的名称 - 这是更多的工作,而不是更少.此外,作为一般规则,当语言允许您更灵活并且不强加特定的思维方式来做某事时,它会更好.良好设计的一部分是知道你不可能提前预测每种情况,并知道何时违反规则. (10认同)
  • @dferraro:我不同意.有时在类中使用嵌套类型是完全有效的,并且最好将该嵌套类型赋予其自己的文件. (6认同)
  • @dferraro:我为错字和我不专业的不成熟道歉.感谢您设置示例. (6认同)
  • "范围括号的折叠"是IDE功能,而不是语言功能.此外,由于功能与复杂性之间的权衡太大,并不是因为没有多重继承必然是一个很好的限制,因此不包括多重继承.最后,从更个人的角度来看,我认为有很多事情可以像政府一样无言,与你的断言相反. (4认同)
  • @dferraro:不,我们不知道你的意思; 这就是为什么我们澄清了!许多人在假设错误的情况下来到SO,因此最明智的行动方式通常是弄清楚这些假设是先行的.如果不先问我们,我们不知道你相信或不相信,所以我们这样做. (3认同)
  • @dferraro:最近有一个名声重新计算,以回答问题的答案.您可以在blog.stackoverflow.com上阅读更多内容. (3认同)

Jef*_*tes 12

我会(并且确实)使用部分类有两个原因.

  1. 分离代码的自动生成部分(例如WinForms设计器代码或T4输出).
  2. 允许嵌套类型自己的文件,同时仍然实现设计所需的封装.

更新
我可以看到有些人不相信我的第二点,所以让我举个例子; 该ListViewItemCollection框架中.它是非常正确的嵌套,ListView因为它仅供使用ListView,但为了使维护更容易,我会通过使用部分类给它自己的文件.我不认为这是错误的设计或滥用partial关键字.

有关更多讨论,请查看此重复的问题:C#中的部分类

  • 出于第二个原因,我也使用了partials. (2认同)

Aar*_*ght 11

部分类的另一个合法用途是帮助减少WCF中的"单片Web服务"混乱.您希望将其分解为逻辑功能组,但不希望创建单个服务实例/端点的扩展(可能是因为它们共享状态,资源等).

解决方案?使服务实现多个接口,并在其自己的分部类中实现每个接口.然后将配置中的不同端点映射到同一物理实现.它使项目更易于维护,但您仍然只有一个物理端点.

在某些情况下,由于SRP的原因,我认为这种方法是一种不好的做法,但是当你正在使用WCF服务或Web服务时,它并不是那么简单.您必须平衡内部设计要求与外部消耗要求.


Jon*_*n M 7

一个较不常见的用途可能是将一个庞大的类拆分为单独的物理文件,从源代码管理的角度来看,这样可以简化生活.我刚刚加入了一个项目,其中包含一些非常臃肿的Web服务类,这些类运行到数千行代码,并且具有与几个不同业务功能相关的方法.

由于不同的团队在同一文件中同时进行无关的更改,因此从各种功能分支进行合并是一场噩梦.我不能在没有做出一些严重破坏性更改的情况下拆分Web服务,但是将类分解为部分类可以完全保留行为,并消除了一大堆合并问题.

我绝对不鼓励将上述作为一种设计选择,但这对我们来说是一个很好的快速胜利,并且表明偏见并非始终是邪恶的......