C#的部分类是不好的devise?

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

无论如何,长话短说 – 他在整个地方使用部分类,以此来伪造C#(IMO)中的多重inheritance。 他为什么不把课程分成多个class,用作文是超越我的。 他将有3个“部分类”文件来构成他的基类,每个文件都有3-500行代码……并且在他的API中多次执行。

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

编辑:我知道,对于Web / WinForms没有其他select。 但在这之外呢? 为什么没有MS只是把一些不同的关键字粘在代码生成的类中? 还是真的有一个合理的devisescheme是值得的吗?

我不是说这是一个咆哮/战争线程。 我真的很想在这里学习一些东西。 什么时候应该在代码devise中使用部分类? 简单的问题,不需要closures

谢谢

你可以向我解释何时会有一个合理的理由来使用部分课堂?

最合理和有用的原因之一是鼓励将自动生成的代码和您自己的自定义扩展分离。 例如,从某种devise者那里得到一个自动生成的表单代码是很常见的,但是通常你想把自己的特定行为添加进去。 这样,如果重新生成自动代码部分,则不会触及具有特定扩展名的部分。

也就是说,很可能有太多好东西。 一些技巧:

  • 不要让你的partial为了partial

  • 除了彼此之外,不要把部分课程放在任何地方。 如果你不得不跳到一个完全不相关的项目部分去看另一半class级,那么你可能做错了。

  • 不要使用partial作为一种技术来模糊类的大小。 如果因为分数过大而partial分class,则应重新考虑单一责任原则

  • 如果同一个class级有三个或更多partial片段,则几乎可以保证您滥用部分内容。 二是合理性的典型上限,一般用于从手写代码中分割自动生成的代码。

无论如何,长话短说 – 他在整个地方使用部分类,以此来伪造C#(IMO)中的多重inheritance。 为什么他没有把课堂分成多个class级,而是用组合超越了我。 他将有3个“部分类”文件来构成他的基类,每个文件都有3-500行代码……并且在他的API中多次执行。

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

有两个原因,我会(并且)使用部分类。

  1. 分离代码的自动生成部分(如WinFormsdevise器代码或T4输出)。
  2. 允许嵌套types自己的文件,同时仍然实现您的devise所需的封装。

更新
我可以看到有些人不相信我的第二点,所以让我举个例子。 框架中的ListViewItemCollection 。 它是完全正确地嵌套在ListView下,因为它只用于ListView ,但为了使维护更容易,我会通过使用部分类给它自己的文件。 我不认为这是糟糕的devise或误用partial关键字。

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

部分类的另一个合法使用是帮助减lessWCF中的“单一Web服务”混乱。 您想要将其分解为逻辑function组,但不希望创build个别服务实例/端点(可能是因为它们共享状态,资源等)的令牌。

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

在某些情况下,我会指出这种方法是SRP的一个糟糕的做法,但是当您使用WCF服务或Web服务时,并不是那么简单。 您必须在内部devise要求与外部消费要求之间取得平衡。

一个不太常见的用法是将一个巨大的类拆分成单独的物理文件,以便从源代码控制的angular度来简化生活。 我刚刚join了一个项目,其中包含一些庞大的Web服务类,这些Web服务类运行着数千行代码以及与几种不同业务function相关的方法。

从不同的function分支合并是一个噩梦,由于不同的团队在同一个文件中同时做出不相关的更改。 我不能把Web服务拆分成一些严重的破坏性的变化,但是将类拆分成部分类可以精确地保留行为,并消除大量的合并问题。

我绝对不鼓励上述作为devise的select,但是对我们来说这是一个很好的快速胜利,并且表明分数并不是一直都是邪恶的。

过去我曾经以许多不同的方式使用部分类。 随着我对编程的了解越来越多,特别是“偏好inheritance”这个概念,我可以很容易地看到垂直inheritance和部分类过度使用的需求正在减less。

除了自动生成的代码之外,我无法想到使用部分类。 即使您使用EF,并且需要不同的元数据,他们甚至不build议使用元数据的部分。 事实上,如果您尝试复制另一个部分中的任何属性(只是为了添加元数据),您将得到一个编译器错误。

我们对重构和SOC(分离关注点)了解得越多,我们的类就越小,越集中。 他们默认情况下,重新使用,随着时间的推移,使他们防弹,易于testing。 只是对庞大的节目说不。 亨利·福特在二十世纪初学会了这个概念,程序员在100年后开始学习。

当你可以使用组合…

我完全同意约翰的回答。 但我会更进一步。

  • 不要让你的课程部分。

部分类的唯一用处我能想到,我认为“好devise”是自动生成的代码。 任何其他用途几乎肯定会不必要地分裂你的class级。 (其实,我可以看到Jeff的嵌套类的第二点可能是一个有效的用法)

就我个人而言,我认为你正在阅读的这本书听起来像是糟糕的devise,但是他认为他可能只是使用部分类,所以他可以一次演示部分代码,而不是一次性提交整个课程。

你可以向我解释何时会有一个合理的理由来使用部分课堂?

Visual Studio的最新版本使用部分类来分离自己生成的devise器代码。

一个ASP.NET示例:

  • Page.aspx
  • Page.aspx.cs < – 您的代码
  • Page.aspx.Designer.cs < – 包含自动生成的代码的部分类。

一个WinForms例子:

  • Form1.resx中
  • Form1.cs < – 您的代码
  • Form1.Designer.cs < – 包含自动生成的代码的部分类

我已经使用了部分类在活动logging体系结构中将业务类属性和方法中的静态数据访问方法“物理”分离。 例如,我们有Company和CompanyData部分类并排。 优点是一个文件是POCO,另一个文件只包含数据访问方法。 这是在遗留应用程序中删除对存储库类的数据访问的垫脚石。 我认为这是一个合法的使用,它确实使重新分解过程更加安全。

另一个很好的用于部分类的实现抽象工厂模式 。 将根工厂对象设为部分,然后将实际的工厂方法放在与工厂实例化的类相同的文件中。

编辑:部分类也适用于与configuration文件交互的类。 将包含configuration参数的代码放在实际使用configuration参数的代码附近。

只是偶然发现这个线程,同时search部分类的好处。 我正在将Java EE应用程序转换为基于Silverlight的.NET应用程序。 我在查看图层中遇到以下代码:

 //------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // Runtime Version:4.0.30319.225 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ ... public partial class Wwcusts04d : System.Windows.Controls.Page { 

现在,如果部分页面本身是自动生成的,维护它的用处是什么? 另外,里面的代码只是将各种控件链接到他们的名字。 我不承认有Silverlight的知识,但不是更适合在xaml这个东西?

部分类存在于.Net框架中, 目的是让Visual Studiodevise人员(例如,Asp.Netdevise人员和Windows窗体devise人员)在生成的代码保存在单独的文件中时生成代码/混乱的类。

(请参阅.NET部分类与inheritance )

如果你做了类似的事情(生成需要与用户编写的代码共存的代码),那么你也可能会发现部分类是有用的,但我不认为微软有意将部分类作为语言的概念, Visual Studio团队。

它不那么使用部分类是不好的devise – 它只是你可能不会find他们的用途。

我已经在VB.Net中使用过两次部分类,这两次都是因为我很less需要后期绑定。 只需创build一个部分课程并在顶部closuresOption Strict Off。

只是添加到前面提到的分离生成的代码和自定义代码的答案,我发现部分类可用于扩展强types的数据集。

在这个话题上有很多讨论,很多人说:1)使用部分类是不好的devise,2)它被用于自动生成的代码,3)它不应该代替inheritance。

然而,我有一种情况,在这种情况下,部分类看起来会非常方便:我正在构build一系列应用程序,最终将这些应用程序集成到一个套件中。 他们都将有一个主要的forms,将提供一些function,和几个共享的组件(例如,一个窗体来显示报告)。 虽然我可以定义一个基类并从中inheritance,但是在将所有应用程序合并到产品的“企业”版本时,这意味着很多返工。

因此,部分类是非常有用的,因为我可以很简单地将各种部分类包含到组合版中,同时还允许我构build单独的独立版本的产品。 如果我试图使用inheritance来实现这个function,那么我最终会调用每个组件调用它自己版本的公共组件(例如InvoiceReportViewer,PurchasingReportsViewer等),而不是简单地调用ReportsViewer,并知道Visual Studio将集成所有的位对我来说。

另一件需要考虑的事情是, 部分类迫使你创build包含相同类名的不同文件名 。 例如,你有FactoryClass,你正在创build它的部分版本, Factory.designer.cs,Factory.data.cs和所有这些文件都有名为FactoryClass的类。

如果你导航到这个问题; 有一个最佳实践定义为:

但是,最佳做法是为每个文件定义一个类,并为该文件定义与类(或结构等)相同的名称。