C#中的分部类
本文关键字: | 更新日期: 2023-09-27 17:48:54
在webforms/winforms生成的代码场景之外,分部类是否有很好的用途?或者这个功能基本上是为了支持这一点?
它在一定程度上支持将生成的代码与程序员代码混合的场景(WebForms、WinForms、LINQ to SQL等)。
使用它有更多的理由。例如,如果你在大而笨拙的文件中有大类,但这些类有一组逻辑相关的方法,那么分部类可能是一个选项,可以让你的文件大小更易于管理。
代码生成是部分类背后的驱动力。这种需求来自于拥有一个不断变化的代码生成类,但允许开发人员提供自定义代码作为类的一部分,每次进行强制重新生成类的更改时,这些代码都不会被覆盖。
以WinForms或Typed数据集为例(或任何与此相关的设计器)。每次对设计器进行更改时,它都会将相应的代码序列化到文件中。假设您需要提供一些生成器一无所知的其他方法。如果将其添加到生成的文件中,则在下次生成时所做的更改将丢失。
我目前正在进行的一个项目使用所有DAL、BLL和商业实体的代码生成。然而,生成器只向我们提供75%的信息。剩下的部分必须手工编码(例如自定义业务逻辑)。我可以假设每个BLL类都有一个SelectAll方法,所以很容易生成。但是,我的客户BLL也需要一个SelectAllByLocation方法。我不能把它放在我的生成器中,因为它不是所有BLL类的泛型。因此,我将所有类生成为分部类,然后在一个单独的文件中定义我的自定义方法。现在,当我的结构发生变化,或者出于某种原因需要重新生成BLL时,我的自定义代码不会被删除。
我使用分部类来分离我编写的自定义控件的不同子元素。此外,当与实体创建软件一起使用时,它允许LLBLGen等产品创建生成的类版本,以及自定义的用户编辑版本,如果需要重新生成实体,这些版本不会被替换。
我经常使用分部类为每个嵌套类提供自己的文件。我曾经研究过一些体系结构,其中大多数实现只需要一个类,所以我们将这些类嵌套在那个类中。通过使用分部类功能并将每个文件拆分为自己的文件,使文件更易于维护是有意义的。
我们还使用它们对股票覆盖进行分组或隐藏股票属性集。诸如此类的事情。这是一种混合库存更改的方便方法(只需复制文件并将部分类名更改为目标类——当然,只要目标类也是部分的)。
分部类的另一个可能用途是利用分部方法,使用条件编译使方法选择性地消失-这对于调试模式诊断代码或专用单元测试场景非常有用。
您可以声明一个有点像抽象方法的分部方法,然后在另一个分部类中,当您键入关键字"分部"时,您可以利用Intellisense来创建该方法的实现。
如果用条件构建语句包围一个部分,那么可以很容易地切断仅调试或测试代码。在下面的示例中,在DEBUG模式下,会调用LogSomethingDebugOnly方法,但在发布版本中,该方法似乎根本不存在——这是一种很好的方法,可以使诊断代码远离生产代码,而无需一堆分支或多个条件编译块。
// Main Part
public partial class Class1
{
private partial void LogSomethingDebugOnly();
public void SomeMethod()
{
LogSomethingDebugOnly();
// do the real work
}
}
// Debug Part - probably in a different file
public partial class Class1
{
#if DEBUG
private partial void LogSomethingDebugOnly()
{
// Do the logging or diagnostic work
}
#endif
}
LINQ to SQL充分利用分部类来扩展设计器生成的代码。我想您通常会发现这种由设计器创建的代码使用的分部类模式。
我发现分部类非常有用。通常,它们被用来扩展自动生成的类。我在一个有大量单元测试的项目中使用了它们。我的UT类有复杂的依赖关系,在多个类之间分离代码不是很实用。当然,最好使用继承''组合,但在某些情况下,分部类可能会非常有用。
如前所述,我也认为这是一种代码气味。
如果一个类太大,需要拆分成更多的文件,这意味着它违反了单一责任原则,做了太多的事情。大的阶级可以被分解成小的阶级一起合作。
如果必须使用分部类或区域来组织代码,请考虑它们是否应该在自己的类中。它提高了可读性,并且可以获得更多的代码重用。
一般来说,我认为这是一种代码气味。
如果你的类那么复杂,那么它可能会被分解成更小的可重用组件。
或者这意味着在应该有继承层次的地方没有继承层次。
对于代码生成场景来说,这很好,但我认为代码生成是另一种代码气味。
也许太晚了,但请让我也加2美分:
*。在处理大型项目时,将一个类分散在不同的文件上可以让多个程序员同时处理它。
*。您可以轻松地为VS.NET生成的类编写代码(用于扩展功能)。这将允许您编写自己需要的代码,而不会干扰系统生成的代码
在我所在的地方,我们有一个程序可以处理来自客户端的传入文件。它的设置使每个客户端的代码都在自己的类库项目中,该项目知道如何处理客户端选择使用的任何格式。
主代码通过定义库中的类必须实现的相当广泛的接口来使用库(可能应该是几个不同的接口,但现在更改它已经太晚了)。有时,同一类中涉及的代码比我们通常认为的谨慎要多得多。部分课程允许我们在一定程度上分解它们。
在相对复杂的UserControls上,我把事件处理的东西放在一个文件中,把绘画和属性放在另一个文件。分部类在这方面做得很好,通常类的这些部分是相对独立的,能够并排编辑绘画和事件处理是很好的。
几年前,我参与了一个项目,在这个项目中,我们有一个类型化的DataSet类,其中包含大量代码:DataTables中的方法、TableAdapters中的方法和TableAdapter实例的声明,并且在部分类代码文件上存在许多源代码管理争用。
因此,我将代码文件拆分为fix或六个部分类文件,按函数分组,这样我们就可以处理较小的部分,而不必每次更改一些小东西时都锁定整个文件。
(当然,我们也可以通过不使用完全锁定的源代码控制系统来解决这个问题,但这是另一个问题。)
我在游戏中迟到了。。。但只有我的2美分。。。
一种用途可以是将现有遗留代码库中的现有god类重构为多个分部类。如果对包含分部类的文件名遵循正确的命名约定,它可以提高代码的可发现性。这也可以在一定程度上减少源代码存储库的解析和合并。
理想情况下,一个神类应该被分解为多个小类——每个小类都有一个职责。有时,执行中大型重构会造成中断。在这种情况下,部分课程可以提供暂时的缓解。
正如Matt所指出的那样,更正部分的两侧需要在同一个组件中。我的坏。
我在数据访问层中使用它。生成的类类似于映射器和查询的分部。例如,如果我需要添加一个mapper方法来进行未生成的花式加载,我会将其添加到自定义类中。
最后,在业务层中使用数据层的程序员只看到一个类具有他或她需要的所有功能。如果数据源发生更改,则可以在不覆盖自定义内容的情况下轻松生成通用部件。
我刚刚发现了分部类的用法。我有一个[DataContract]类,用于将数据传递给客户端。我希望客户端能够以特定的方式显示类(文本输出)。所以我创建了一个分部类并重写了ToString方法。
有时您可能会发现工作中的代码非常旧,这可能会使您几乎不可能在不破坏现有代码的情况下重构为不同的元素。
当你没有选择或时间创建一个更真实的体系结构时,分部类可以让你非常容易地将逻辑分离到需要的地方。这允许现有代码继续使用相同的体系结构,同时离更具体的体系结构又近了一步。
以前使用过#region
节的任何地方作为分部类中的单独文件可能更有意义。
我个人将分部类用于大型类,其中静态成员位于一个文件中,实例成员位于另一个文件。
EDIT:DSL Tools for Visual Studio使用分部类。
因此,这是许多自动生成的代码使用的一个功能。自动生成的代码不使用#region,而是放在一个文件中,用户代码(也称为自定义代码)放在另一个文件,甚至放在不同的目录中,这样开发人员就不会被这么多毫无意义的文件弄糊涂。
有这样的选择是很好的,你可以将其与继承结合使用,但不能强制使用
此外,在几个目录中分离某些类的逻辑也很方便。当然,对于机器来说,这是一样的,但它增强了用户的可读性体验。