C#分部方法的应用场景
C#分部方法和分部类型的初衷是类似的,一方面可以使得不同的开发者能够同时编写一个类型的不同部分,另一方面可以分离自动生成的代码和用户手写的代码。和分部类型一样,分部方法也会在编译初期被合并成一个方法定义。猜测:从微软的角度来看,第二个“初衷”可能才是真正的初衷。
由此,分部方法有如下几个应用场景:
场景1 出自In Case You Haven't Heard这篇文章
场景2 出自Visual Studio 2008的Linq to SQL技术
场景3 则是Anders Liu自已臆想出来的。
C#分部方法场景1 轻量级事件处理
有的时候,自动生成的代码需要事件这类语言构造来通知用户对某些操作进行处理,但实际上用于编写的代码就位于自动生成的类型之中。此时,或者需要触发一个事件,或者就需要生成一个virtual方法来让用户继承。但无论是事件还是继承,开销都是比较大的,所以可以通过分部方法来实现轻量级的处理方式。如下面的类:
- partialclassCustomer
- {
- stringname;
- publicstringName
- {
- get
- {
- returnname;
- }
- set
- {
- OnBeforeUpdateName();
- OnUpdateName();
- name=value;
- OnAfterUpdateName();
- }
- }
- partialvoidOnBeforeUpdateName();
- partialvoidOnAfterUpdateName();
- partialvoidOnUpdateName();
- }
这里定义了三个分部方法,其意义不言而喻。假设这是系统自动生成的代码,则我们只需在另外一个源代码文件中的partial class Customer中实现这几个分部方法即可。
C#分部方法场景2 自定义DataContext中的Insert、Update、Delete方法
当使用Linq to SQL向项目中加入了实体类之后,还会创建一个XxxDataContext类,这个类继承自DataContext类,并且是partial的。这个类封装了具体的数据库操作功能(实体类仅封装数据库中的数据),如对象的插入、更新和删除等。
下面我们来看一下这个自动生成的类定义:
- publicpartialclassAdventureWorksDataContext:System.Data.Linq.DataContext
- {
- privatestaticSystem.Data.Linq.Mapping.
MappingSourcemappingSource=newAttributeMappingSource();- #regionExtensibilityMethodDefinitions
- partialvoidOnCreated();
- partialvoidInsertAWBuildVersion(AWBuildVersioninstance);
- partialvoidUpdateAWBuildVersion(AWBuildVersioninstance);
- partialvoidDeleteAWBuildVersion(AWBuildVersioninstance);
这里我们可以看到一系列的partial方法。其中第一个OnCreated实际上属于场景1中描述的情况,是一个轻量级的事件,表示 DataContext环境对象创建完毕。而其他partial方法则用于自定义DataContext的IUD操作。对于每一个表(实体类),这里都会出现一组InsertXxx、UpdateXxx和DeleteXxx方法。如果我们希望自定义删除行为(如希望将一个IsDelete字段设置为 true来表示已删除),则可以在另一个文件中扩展这个partial类,并为对应的Delete方法提供实现声明。
C#分部方法场景3 新的调试信息输出方法
这是Anders Liu臆想的场景,在分部方法的协助下,我们可以写出这样的代码:
- partialclassCA
- {
- partialvoidDebugPrint(stringmsg);
- ...
- voidF()
- {
- ....
- DebugPrint("aaa");
- }
- }
- partialclassCA
- {
- #ifDEBUG
- partialvoidDebugPrint(stringmsg);
- {
- Debug.WriteLine(msg);
- }
- #endif
- }
这样做的好处在于,我们还是反过来说罢,如果不这样做,必须在每次调用调试代码时都加入#if判断。而这样可以将调试代码都写成方法,在一处用#if进行判断。
缺点在于,由于分部方法必须是私有的,所以必须针对每个类写一套调试代码。以上介绍C#分部方法的应用场景。
【编辑推荐】