C# 3.0中如何使用部分类方法?

18

我已阅读最新的C#语言规范中有关局部方法的内容,因此我理解了原理,但我想知道人们实际上如何使用它们。是否有一种特定的设计模式可以从局部方法中受益?


I了解局部方法的原理,但我想知道人们实际上如何使用它们。是否有一种特定的设计模式可以从局部方法中受益?
5个回答

23

为了类似于.NET 2中分部类的原因,引入了部分类。

部分类是可以跨多个文件拆分的类 - 编译器在运行时将它们全部构建成一个文件。

这样做的好处是,Visual Studio可以为类的一部分提供图形化设计,同时程序员可以在另一部分上工作。

最常见的例子是表单设计器。开发人员大多数情况下不想手动定位按钮、输入框等。

  • 在.NET 1中,这是自动生成的代码在#region块中
  • 在.NET 2中,这些变成了单独的设计器类 - 表单仍然是一个类,只是分成一个由开发人员编辑的文件和一个由表单设计器编辑的文件

这使得维护变得更加容易。合并更简单,VS表单设计器意外撤销程序员手动更改的风险更小。

.NET 3.5中引入了Linq。Linq有一个DBML设计器用于构建数据结构,并生成自动代码。

额外的问题在于需要提供开发人员可能想要填写的方法的代码。

由于开发人员将扩展这些类(使用额外的部分类文件),因此无法在此处使用抽象方法。

另一个问题是大多数情况下这些方法不会被调用,调用空方法是浪费时间的。

空方法不会被优化掉

因此Linq生成了空的部分类方法。如果您没有创建自己的部分类来完成它们,C#编译器将仅对它们进行优化处理。

为了实现这一点,部分类的返回类型始终为void。

如果您创建一个新的Linq DBML文件,它将自动生成一个部分类,类似于:

[System.Data.Linq.Mapping.DatabaseAttribute(Name="MyDB")]
public partial class MyDataContext : System.Data.Linq.DataContext
{
    ...

    partial void OnCreated();
    partial void InsertMyTable(MyTable instance);
    partial void UpdateMyTable(MyTable instance);
    partial void DeleteMyTable(MyTable instance);

    ...

然后在您自己的部分文件中,您可以扩展此文件:

public partial class MyDataContext
{
    partial void OnCreated() {
        //do something on data context creation
    }
}

如果您不扩展这些方法,它们将被优化掉。
部分类方法不能是公共的,因为其他类需要调用它们。如果您编写自己的代码生成器,则可以看到它们很有用,否则它们只对VS设计人员真正有用。
我之前提到的示例是一种可能性:
//this code will get optimised out if no body is implemented
partial void DoSomethingIfCompFlag();

#if COMPILER_FLAG
//this code won't exist if the flag is off
partial void DoSomethingIfCompFlag() {
    //your code
}
#endif

另一个潜在的用途是,如果您有一个跨多个文件分散的大型和复杂的类,您可能希望在调用文件中使用部分引用。不过,在这种情况下,我认为您应该先考虑简化类。


3
好的答案;为了增加一点点价值,局部类也可以用于向自动生成的 Web 服务类中添加方法和功能。 - TheXenocide
@Keith:“局部方法不能是公共的 - 因为那样它们就必须存在于其他类中才能被调用。”我认为这个限制是无效的,例如在我的项目中,我有大约15个方法在一个类中,为了更好的可读性,我想将它们保留在局部类中。但由于我不能将它们定义为公共的,所以我被迫将它们保留在同一个类中。 - user348675

10

Partial methods(部分类方法)的概念与GoF的模板方法行为模式非常相似(Design Patterns, p325)。

它们允许在一个地方定义算法或操作的行为,并在其他地方实现或更改,从而实现可扩展性和定制化。我已经开始在C# 3.0中使用部分类方法而不是模板方法,因为我认为代码更加简洁。

一个好处是未实现的部分类方法不会产生运行时开销,因为它们被编译器优化掉了。


是的,真的!这是一件很神奇的事情 - 一个人(你)看到了其他人(我)没有看到的东西。 - zzfima

2

代码生成是它们存在的主要原因之一,也是使用它们的主要原因之一。


编辑:尽管该链接是针对Visual Basic特定信息的,但相同的基本原则也适用于C#。


2

我认为它们是轻量级的事件。你可以拥有一个可重用的代码文件(通常是自动生成的,但不一定如此),对于每个实现,只需在部分类中处理你关心的事件。事实上,这就是LINQ to SQL中使用它的方式(也是发明该语言特性的原因)。


0

这里是关于C#.NET 3.0中partial classes的最佳资源:http://msdn.microsoft.com/en-us/library/wa80x488(VS.85).aspx

我尽量避免使用partial classes(除了Visual Studio为设计文件创建的partials,那些很棒)。对我来说,将一个类的所有代码放在一个地方更为重要。如果你的类设计良好且代表一件事情(单一职责原则),那么该事情的所有代码应该在一个地方。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接