什么时候使用C#分部类合适?

什么时候使用C#分部类合适?,c#,class,architecture,C#,Class,Architecture,我想知道是否有人能给我一个概述,说明我为什么要使用它们,以及在这个过程中我会获得什么好处。一个很好的用途是将生成的代码与属于同一类的手写代码分开 例如,由于LINQ to SQL使用分部类,因此您可以编写自己的某些功能(如多对多关系)的实现,并且在重新生成代码时这些自定义代码不会被覆盖 WinForms代码也是如此。所有设计器生成的代码都放在一个文件中,您通常不会触及该文件。您的手写代码将放入另一个文件中。这样,当您在Designer中更改某些内容时,您的更改不会被吹走。部分类的主要用途是生成代

我想知道是否有人能给我一个概述,说明我为什么要使用它们,以及在这个过程中我会获得什么好处。

一个很好的用途是将生成的代码与属于同一类的手写代码分开

例如,由于LINQ to SQL使用分部类,因此您可以编写自己的某些功能(如多对多关系)的实现,并且在重新生成代码时这些自定义代码不会被覆盖


WinForms代码也是如此。所有设计器生成的代码都放在一个文件中,您通常不会触及该文件。您的手写代码将放入另一个文件中。这样,当您在Designer中更改某些内容时,您的更改不会被吹走。

部分类的主要用途是生成代码。如果查看WPF(Windows Presentation Foundation)网络,您可以使用标记(XML)定义UI。该标记被编译成分部类。使用自己的分部类填充代码。

分部类的最大用途是使代码生成器/设计人员的工作更轻松。分部类允许生成器只发出它们需要发出的代码,而不必处理用户对文件的编辑。用户同样可以通过拥有第二个分部类,自由地使用新成员对类进行注释。这为分离关注点提供了一个非常干净的框架


更好的方法是查看设计器在部分类之前是如何工作的。WinForms设计器会在一个区域内吐出所有代码,并给出关于不修改代码的措辞强硬的注释。它必须插入各种试探法来找到生成的代码,以便以后处理。现在,它可以简单地打开designer.cs文件,并且非常确信它只包含与设计器相关的代码

如果您有一个足够大的类,而该类本身不适合进行有效的重构,那么将其拆分为多个文件有助于保持组织

例如,如果您有一个包含讨论论坛和产品系统的站点数据库,并且您不想创建两个不同的提供者类(与代理类不同,这一点很清楚),那么您可以在不同的文件中创建一个分部类,如

MyProvider.cs-核心逻辑

MyProvider.Forum.cs-专门与论坛相关的方法

MyProvider.Product.cs-产品的方法

这只是另一种让事情井然有序的方式


另外,正如其他人所说,这是将方法添加到生成的类中的唯一方法,而不会在下次重新生成该类时导致添加内容被破坏。这对于模板生成(T4)代码、ORM等非常方便。

服务引用是另一个示例,其中分部类可用于将生成的代码与用户创建的代码分开


更新服务引用时,您可以“扩展”服务类,而不会覆盖它们。

除了其他答案之外

我发现它们可以作为重构god类的垫脚石。如果一个类有多个职责(特别是当它是一个非常大的代码文件时),那么我发现在每个职责中添加1个分部类作为组织和重构代码的第一步是有益的

这非常有帮助,因为它可以使代码更具可读性,而不会实际影响执行行为。它还可以帮助确定责任何时容易重构或与其他方面紧密纠缠


然而,需要明确的是,这仍然是糟糕的代码,在开发结束时,您仍然希望每个类承担一项责任(而不是每个部分类)。它只是一块垫脚石:)

作为预编译器指令的替代品

如果您使用预编译器指令(即
#If DEBUG
),那么最终会出现一些看起来粗糙的代码与实际发布代码混合在一起


您可以创建一个单独的分部类来包含此代码,或者将整个分部类包装在一个指令中,或者忽略发送给编译器的代码文件(实际上也是这样做的)。

在处理大型类时,或者在团队中工作时,您可以在不重写的情况下进行编辑(或始终提交更改)

部分类使得仅通过添加源文件就可以向适当设计的程序添加功能。例如,可以设计文件导入程序,以便通过添加处理模块来添加不同类型的已知文件。例如,主文件类型转换器可以包括一个小类:

Partial Public Class zzFileConverterRegistrar Event Register(ByVal mainConverter as zzFileConverter) Sub registerAll(ByVal mainConverter as zzFileConverter) RaiseEvent Register(mainConverter) End Sub End Class 部分公共类zzFileConverterRegistrar 事件寄存器(ByVal mainConverter作为zzFileConverter) 子寄存器ALL(ByVal mainConverter作为zzFileConverter) RaiseEvent寄存器(主转换器) 端接头 末级 希望注册一种或多种类型文件转换器的每个模块可以包括以下内容:

Partial Public Class zzFileConverterRegistrar Private Sub RegisterGif(ByVal mainConverter as zzFileConverter) Handles Me.Register mainConverter.RegisterConverter("GIF", GifConverter.NewFactory)) End Sub End Class 部分公共类zzFileConverterRegistrar 私有子寄存器GIF(ByVal mainConverter作为zzFileConverter)处理Me.Register mainConverter.RegisterConverter(“GIF”,GifConverter.NewFactory)) 端接头 末级 注意,主文件转换器类不是“公开的”——它只公开了一个小存根类,外接程序模块可以钩住它。命名冲突的风险很小,但是如果每个外接程序模块的“注册”例程是根据它处理的文件类型命名的,那么它们可能不会造成问题。如果担心这些事情,可以在注册子例程的名称中添加GUID

编辑/补遗 明确地说,这样做的目的是提供一种方法,通过这种方法,各种不同的类可以让主程序或类了解它们。主文件转换器将使用zzFileConverterReg执行的唯一操作 RegisterConverter("GIF", GifConvertor.NewFactory) RegisterConverter("BMP", BmpConvertor.NewFactory) RegisterConverter("JPEG", JpegConvertor.NewFactory)
partial class MyClass : IF3
{
    // main implementation of MyClass
}


partial class MyClass : IF1
{
    // implementation of IF1
}

partial class MyClass : IF2
{
    // implementation of IF2
}
in Post.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of post..
}


in Comment.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of comment..
}

in Pages.cs 

public partial class XMLDAO :BigAbstractClass
{
// CRUD methods of Pages..
}
public partial class Product
{
    // 50 business logic embedded in methods and properties..
}

public partial class Product
{
    // another 50 business logic embedded in methods and properties..
}
//finally compile with product.class file.
public partial class Product
{
    //you are writing the business logic for fast moving product
}
public partial class Product
{
    // Another developer writing some business logic...
}
partial void Ontest(string s);
class Program
{
    static void Main()
    {
        A.A1();
        A.A2();
    }
}
using System;

partial class A
{
    public static void A1()
    {
        Console.WriteLine("A1");
    }
}
using System;

partial class A
{
    public static void A2()
    {
        Console.WriteLine("A2");
    }
}
A1
A2
internal class A
{
    // Methods
    public static void A1()
    {
        Console.WriteLine("A1");
    }

    public static void A2()
    {
        Console.WriteLine("A2");
    }
}
[SerializableAttribute]
partial class Moon { }

[ObsoleteAttribute]
partial class Moon { }
[SerializableAttribute]
[ObsoleteAttribute]
class Moon { }
partial class ClassWithNestedClass
{
    partial class NestedClass { }
}

partial class ClassWithNestedClass
{
    partial class NestedClass { }
}
public class MyClass{  
  //Member variables
  //Constructors
  //Properties
  //Methods
}
//Methods - See partial class